Related
Hey I'm new to lists and modules can you show me how to do this. I actually tried this code but it seems to be giving me a wrong answer
l = [1, 2, 3, 4, 5]
fact = 1
for i in l:
for number in range(1,i+1):
fact=fact*number
print ("Factorial of", i, "is", fact)
def factorial(n):
if n < 2:
return 1
else:
return n * factorial(n-1)
l = [1, 2, 3, 4, 5]
for number in l:
fact = factorial(number)
print("Facotrial of ",number," is",fact)
Here is a working example.
You can use the balise code to better show your code, I have trouble to read it so I can't really comment on what you did wrong
e.g. [a,a,c,e] and [a,b,c,d,e]. This is what I mean by same order. It shouldn't matter if one of the lists is only partial. To be clear, I am uninterested in sorting anything.
Edit: Apparently I should mention that I mean lists with some different values. e.g. [a,a,c,e] and [a,b,c,d,e] are in the same order. Simply getting rid of duplicates and cutting the bigger list won't work.
We can use itertools.groupby to squash identical consecutive items into a single item of that value. We can then zip together the squashed values with the other list to see if they are the same
from itertools import izip, groupby
def squash(iterable):
return (k for k, _ in groupby(iterable))
def same_order(iterable, reference):
return all(x == y for x, y in zip(squash(iterable), reference))
print(same_order((1, 2, 2, 3, 4), (1, 2, 3, 4, 5)))
# True
print(same_order((1, 2, 2, 1, 3, 4), (1, 2, 3, 4, 5)))
# False
You can first take the unique set of b, then truncate to the size of a (or vice versa)
a = [1,2,3,4]
b = [1,1,2,2,3,4,4,5]
a == list(set(b))[:len(a)]
You can achieve this by first getting the unique elements from partial list a (in the order of a), then get those elements from full list b (in the order of b). Then you can compare the two and see if they are identical.
>>> a = [1, 1, 4, 3]
>>> a = sorted(set(a), key=a.index) # Remove duplicate elements, but keep the original order
>>> a
[1, 4, 3]
>>> b = [1, 2, 4, 3, 5]
>>> b = [x for x in sorted(set(b), key=b.index) if x in a] # Get unique elements of a from b in order of b, and filter them out to get only elements present in a
>>> a == b
True
>>> a = [4, 3, 2, 1]
>>> a = sorted(set(a), key=a.index) # Remove duplicate elements, but keep the original order
>>> b = [1, 2, 4, 3, 5]
>>> b = [x for x in sorted(set(b), key=b.index) if x in a] # Get unique elements of a from b in order of b, and filter them out to get only elements present in a
>>> a == b
False
If I have an input like this (1, 2, 3, 4, 5, 6)
The output has to be ... [[1, 2], [3, 4], [5, 6]].
I know how to deal with if it's one element but not two.
x=[]
for number in numbers:
x.append([number])
I'll appreciate your any help!
Something like this would work:
out = []
lst = (1,2,3,4,5,6,7,8,9,10)
for x in range(len(lst)):
if x % 2 == 0:
out.append([lst[x], lst[x+1]])
else:
continue
To use this, just set lst equal to whatever list of numbers you want. The final product is stored in out.
There is a shorter way of doing what you want:
result = []
L = (1,2,3,4,5,6,7,8,9,10)
result = [[L[i], L[i + 1]] for i in range(0, len(L) - 1, 2)]
print(result)
You can use something like this. This solution also works for list of odd length
def func(lst):
res = []
# Go through every 2nd value | 0, 2, 4, ...
for i in range(0, len(lst), 2):
# Append a slice of the list, + 2 to include the next value
res.append(lst[i : i + 2])
return res
# Output
>>> lst = [1, 2, 3, 4, 5, 6]
>>> func(lst)
[[1, 2], [3, 4], [5, 6]]
>>> lst2 = [1, 2, 3, 4, 5, 6, 7]
>>> func(lst2)
[[1, 2], [3, 4], [5, 6], [7]]
List comprehension solution
def func(lst):
return [lst[i:i+2] for i in range(0, len(lst), 2)]
Slicing is better in this case as you don't have to account for IndexError allowing it to work for odd length as well.
If you want you can also add another parameter to let you specify the desired number of inner elements.
def func(lst, size = 2): # default of 2 it none specified
return [lst[i:i+size] for i in range(0, len(lst), size)]
There's a few hurdles in this problem. You want to iterate through the list without going past the end of the list and you need to deal with the case that list has an odd length. Here's one solution that works:
def foo(lst):
result = [[x,y] for [x,y] in zip(lst[0::2], lst[1::2])]
return result
In case this seems convoluted, let's break the code down.
Index slicing:
lst[0::2] iterates through lst by starting at the 0th element and proceeds in increments of 2. Similarly lst[1::2] iterates through starting at the 1st element (colloquially the second element) and continues in increments of 2.
Example:
>>> lst = (1,2,3,4,5,6,7)
>>> print(lst[0::2])
(1,3,5,7)
>>> print(lst[1::2])
(2,4,6)
zip: zip() takes two lists (or any iterable object for that matter) and returns a list containing tuples. Example:
>>> lst1 = (10,20,30, 40)
>>> lst2 = (15,25,35)
>>> prit(zip(lst1, lst2))
[(10,15), (20,25), (30,35)]
Notice that zip(lst1, lst2) has the nice property that if one of it's arguments is longer than the other, zip() stops zipping whenever the shortest iterable is out of items.
List comprehension: python allows iteration quite generally. Consider the statement:
>>> [[x,y] for [x,y] in zip(lst1,lst2)]
The interior bit "for [x,y] in zip(lst1,lst2)" says "iterate through all pairs of values in zip, and give their values to x and y". In the rest of the statement
"[[x,y] for [x,y] ...]", it says "for each set of values x and y takes on, make a list [x,y] to be stored in a larger list". Once this statement executes, you have a list of lists, where the interior lists are all possible pairs for zip(lst1,lst2)
Very Clear solution:
l = (1, 2, 3, 4, 5, 6)
l = iter(l)
w = []
for i in l:
sub = []
sub.append(i)
sub.append(next(l))
w.append(sub)
print w
I've been trying to solve this problem for quite sometime and I think the logic I'm attempting is flawed.
The objective is to replace a subsequently decreasing sublist of numbers by the last of the sublist.
?- compare([1, 3, 7, 6, 5, 10, 9], Result).
Result = [1, 3, 5, 9] ;
false.
What I tried was:
compare([A,B|T],X):-
%succ(B,A),
A is B+1,
append([],NextX,X),
compare([B|T],NextX).
remove([A,B|T],X):-
A=\=B+1,
compare([B|T],X).
I'm not certain how to write the base case for the compare/2 and I think the I'm not correctly converting my logic into the code. What I'm trying here is to compare A and B and drop A from the list if they are successive numbers.
Your help is very much appreciated.
You are almost there. First cover the special case: If the list contains only one element it is in the list.
compare([X],[X]).
your second rule just needs little altering:
compare([A,B|T],X):- % A is not in the list if
A is B+1, % A = B+1
compare([B|T],X). % Note: X is the same as in head of rule
Your predicate remove/2 is should be the 3rd rule of compare/2 covering the alternative case:
compare([A,B|T],[A|X]):- % A is in the list
A=\=B+1, % if A is not B+1
compare([B|T],X).
Now the query works:
?- compare([1, 3, 7, 6, 5, 10, 9], Result).
Result = [1,3,5,9] ?
yes
However, this predicate only works if the first list is variable free. You can't use it the other way round:
?- compare([A,B,C], [1,2]).
ERROR at clause 2 of user:compare/2 !!
INSTANTIATION ERROR- X is A+B: expected bound value
If you use library(clpfd) on the other hand ...
:- use_module(library(clpfd)).
compare([X],[X]).
compare([A,B|T],X):-
A #= B+1,
compare([B|T],X).
compare([A,B|T],[A|X]):-
A #\= B+1,
compare([B|T],X).
... the above query works too:
?- compare([A,B,C], [1,2]).
A = C = 2,
B = 1 ? ;
A = 1,
B = 3,
C = 2 ? ;
no
>>> mylist = [ 1, 2, 3 , 5, 'd']
>>> print 'mylist[-1:2] = ',mylist[-1:2]
output is an empty list: []
I am testing around with lists and from what I have so far understood from tutorials made me think the output would be [d, 1, 2]
Can anyone please help me out why isn't that the output?
To understand why your code returns an empty list, it is important to note how accessing list elements in python works. Indexing with : on a python list (or slicing) works like this:
a_list[start:stop:step]
stop must always be greater than start for the list indexing/slicing to work.
When you access an element in the list by using a negative number as the index, say a_list[-1], python adds the length of the list to it and gives you what you want. For ex:
a_list = [1, 2, 3, 4, 5]
a_list[-1] == a[5 - 1]
So when you do mylist[-1:2] it actually means mylist[4:2]. This violates start < stop condition. And hence returns an empty list.
This is what you are looking for:
[mylist[-1]] + mylist[:2]
Slicing with negative numbers (see string slicing) does not make the list a ringbuffer. It's just another way of pointing to an element in the list. So, what you ask for is really: The list beginning at index 4 and ending at index 2. Doesn't make sense, hence you get nothing.
Slicing does not work that way in python. Instead, I suggest creating your own defined function, like below:
>>> def loop(list, start, end):
... array = []
... for k in range(start, end+1):
... array.append(list[k])
... return array
...
>>> x = [1, 2, 3, 4, 5]
>>> desired_output = [5, 1, 2, 3]
>>> loop(x, -1, 2)
[5, 1, 2, 3]
>>> loop(x, -1, 2) == desired_output
True
>>>
This loops over the list, and adds each value of the list to another array, which it then returns.
Or, you can add them together using the following code:
[x[-1]] + x[:2]