split() , to split the list into an ordered collection of consecutive sub-lists. E.g. split([1,2,3,4,5,3,6], 3) -> ([1,2],[4,5],[6]) , as opposed to dividing a list's elements by category. Discussion of the same topic on python-list. IMAGE_TYPES should be a set instead of a tuple: IMAGE_TYPES = set('.
The elements are iterated over using 'enumerate' and depending on the value of the index, the output is determined. If index value is 0, the element in first index is appended to the empty list. If index is equal to length of list minus 1, the element in previous index is appended to empty list.
A tuple can contain a list as an element.
Python tuple is an immutable object. Hence any operation that tries to modify it (like append) is not allowed.
Cleaner Pythonic approach:
>>> [(x,y) for x,y in zip(myList, myList[1:]) if y == 9]
[(8, 9), (4, 9), (7, 9)]
What is the code above doing:
zip(some_list, some_list[1:])
would generate a list of pairs of adjacent elements.9
. You're done :)Part of your issue is that myList[i:i]
will always return an empty list. The end of a slice is exclusive, so when you do a_list[0:0]
you're trying to take the elements of a_list
that exist between index 0 and index 0.
You're on the right track, but you want to zip the list with itself.
[(x, y) for x, y in zip(myList, myList[1:]) if y==9]
You were pretty close, I'll show you an alternative way that might be more intuitive if you're just starting out:
sets = [(myList[i-1], myList[i]) for i in range(len(myList)) if myList[i] == 9]
Get the index in the range of the list lenght, and if the value at the position i
is equal to 9
, grab the adjacent elements.
The result is:
sets
[(8, 9), (4, 9), (7, 9)]
This is less efficient than the other approaches but I decided to un-delete it to show you a different way of doing it. You can make it go a bit faster by using enumerate()
instead:
sets = [(myList[i-1], j) for i, j in enumerate(myList) if j == 9]
Take note that in the edge case where myList[0] = 9
the behavior of the comprehension without zip
and the behavior of the comprehension with zip
is different.
Specifically, if myList = [9, 1, 8, 9, 2, 4, 9, 6, 7, 9, 8]
then:
[(myList[i-1], myList[i]) for i in range(len(myList)) if myList[i] == 9]
# results in: [(8, 9), (8, 9), (4, 9), (7, 9)]
while:
[(x, y) for x, y in zip(myList, myList[1:]) if y==9]
# results in: [(8, 9), (4, 9), (7, 9)]
It is up to you to decide which of these fits your criteria, I'm just pointing out that they don't behave the same in all cases.
You can also do it without slicing by creating iterators:
l = myList = [1,8,9,2,4,9,6,7,9,8]
it1, it2 = iter(l), iter(l)
# consume first element from it2 -> leaving 8,9,2,4,9,6,7,9,8
next(it2, "")
# then pair up, (1,8), (8,9) ...
print([(i, j) for i,j in zip(it1, it2) if j == 9])
Or use the pairwise recipe to create your pairs
from itertools import tee, izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
If using python3, just import tee and use the regular zip.
It is really surprising that no one has added a functional approach.
Another alternative answer is using a filter
. This builtin function returns an iterator (list in Python2) consisting of all the elements present in the list that return True
for a particular function
>>> myList = [1,8,9,2,4,9,6,7,9,8]
>>> list(filter(lambda x:x[1]==9,zip(myList, myList[1:])))
[(8, 9), (4, 9), (7, 9)]
It is to be noted that the list
call is needed only in python3+. The difference between the functional approach and list comprehensions is discussed in detail in this post.
My solution is similar to one of Jim's advanced with zero-index check
myList = [9, 1, 8, 9, 2, 4, 9, 6, 7, 9, 8]
[(myList[i-1], x) for i, x in enumerate(myList) if x==9 and i!=0]
# [(8, 9), (4, 9), (7, 9)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With