Say I have in python a list of tuples
list1 = [(1,1,1), (2,2,2), (3,3,3)]
If I want to separate them into a list of all the 1 position values, 2 position values and 3 position values I would do:
ones = [tuple[0] for tuple in list1]
twos = [tuple[1] for tuple in list1]
threes = [tuple[2] for tuple in list1]
This sort of way can become very cumbersome the more elements each tuple in that list will have. Is there a cleaner way to do this possibly using the zip method or a reverse of it?
You can use zip for this:
list(zip(*list1))
output:
[(1, 2, 3), (1, 2, 3), (1, 2, 3)]
As #paoloaq noted, you can unpack these into separate lists:
ones, two, threes = list(zip(*list1))
or if you want lists instead of tuples:
ones, two, threes = map(list, list(zip(*list1)))
Sidenote: try avoiding variable names like list and tuple.
Related
I am looking for a method to generate all possible combinations of a list of lists, under the condition that there should only be "elementwise" combinations. Thus, if we have the lists [1,2] and [3,4], then the outcome [3,2] is allowed, but [4,2] is not allowed. With itertools.product(*lists) the last outcome is included.
Thus, I want the following output: [1,2], [3,2], [1,4], [3,4], and the following options should be 'skipped': [4,2], [1,3]. Note that the order is important! Thus I do not allow [2,3], just [3,2].
I know that I can check for this afterwards, but since I am generating many many lists in my code, I rather avoid this.
You could store the two lists in one list of lists and then after transposing the container list, use itertools.product() on it.
import itertools
original_list = [[1,2], [3,4]]
transposed_list = list(map(list, zip(*original_list)))
print(list(itertools.product(*transposed_list)))
Outputs:
[(1, 2), (1, 4), (3, 2), (3, 4)]
EDIT | Explaining how the list was transposed:
By definition, transposing is the process of exchanging places.
*original_list means [1,2] and [3,4]. The asterisk refers to the elements of the list, rather than the list as a whole
zip basically pairs values together 'element-wise':
e.g. with our original_list we have [1,2] and [3,4]. Calling zip on our elements will result in (1,3) and (2,4). The values were paired element-wise.
Note that the resulting pairs are not in list form.
map applies a function to every element in an input list. In our example,
we want to apply the (built-in) list function to our element-wise pairs - i.e. convert each tuple of pairs into a list. This is what turns (1,3) and (2,4) into [1,3] and [2,4]
Finally, convert our result from the mapping into a containing list, holding our element-wise pairs, producing [ [1,3], [2,4] ]
I have a list of lists of tuples in the following form:
a = [[( 0, 1),
( 2, 3),
( 4, 5)],
[( 6, 7),
( 8, 9),
(10, 11)],
[(12, 13),
(14, 15),
(16, 17)]]
What I want to do, is to swap the two arguments inside the tuples.
I have tried the two following options, but without succes, the argumets keep their positions:
for i in range(0, len(a)-1):
for j in range(0, len(a)/2):
a[i][j] = a[i][j][1], a[i][j][0]
a[i][j] = tuple(reversed(a[i][j]))
Every help would be very much appreciated
Tuples are immutable, so you should replace the tuples with the reversed tuples, not try to modify the first tuple in-place:
for lst in a:
for i, x in enumerate(lst):
lst[i] = x[::-1]
This takes updates the items at the position of each tuple in the list with a new reversed tuple (with reversed slice notation [::-1]) using list subscription.
To create a new list of lists with the swapped objects, you can use a list comprehension:
new_a = [[tup[::-1] for tup in lst]for lst in a]
Consider changing your loops to:
for i in range(0, len(a)):
for j in range(0, len(a[i])):
a[i][j] = tuple(reversed(a[i][j]))
In order to iterate over a list of lists (of tuples, in this case), you need to make sure you're specifying the lengths of each part correctly. In len(a)-1 in the outer loop, you don't need the -1, as range(x,y) takes you from x to y-1 already. In the inner loop, you need to specify the length of the inner list.
#Moses has a good answer on why creating a new tuple is the correct approach.
I have following lists:
list_1 = [(0, 1, 7, 6), (1, 2, 8, 7), (2, 3, 9, 8), ...]
list_2 = [(0,1), (1,7), (7,8), (3,9), ...]
Both lists have a length of 200000 or more elements.
I need a fast algorithm to check how often an element of list_2 occurs in an element of list_1. In the example above, the second element of list_2 which is (1,7) occurs two times in list_1, respectively in the first and second list element.
In my case it is a valid hit, if both numbers are a subset of list_1 independent of their order. So I thought I go with sets and use .issubset.
for item1 in list_1:
count = 0
for item2 in list_2:
if set(item2).issubset(set(item1)):
count += count
if count == 1:
do this
if count == 2:
do that
The data from the lists are structured in a way, that I know upfront, that the variable count can only have the values 1 or 2. And I know that a loop of O(N**2) is not smart at all and that the if statements in it do not boost performance. Actually, in my current implementation the elements of list_2 are already of type set, but the snippet above is shorter and easy to read.
I believe that there are smart solutions existing for this task.
My application uses numpy and scipy, so any KD-tree search or similar (if applicable) would also be fine.
EDIT
I need to be more specific:
list_2 always contains pairs. list_1 can have 3 or more items per list element.
in do this and do that I need to keep track of the corresponding elements and their associations, e.g by using a dictionary.
there is not more than this to exploit the structure of the data
You could first do some preprocessing and build a dictionary keyed by the individual numbers that occur in list_1 providing each key as value the set of tuples in list_1 that have that keys.
Then finding the occurrences of a pair from list_2 is as simple as taking the intersection of the sets found at the two keys, and taking the resulting set's size.
list_1 = [(0, 1, 7, 6), (1, 2, 8, 7), (2, 3, 9, 8)]
list_2 = [(0,1), (1,7), (7,8), (3,9)]
# per number as dictionary key, list the tuples from list_1 that contain it
d = dict()
for lst in list_1:
for v in lst:
if not v in d: d[v] = set()
d[v].add(lst)
# for each pair, take the intersection of the corresponding lists in d
result = [(lst, len(d[lst[0]].intersection(d[lst[1]]))) for lst in list_2]
print(result)
If you need to actually do something with the found tuples from list_1, then you would first gather those tuples without taking their number (so d[lst[0]].intersection(d[lst[1]])), and do your processing on them based on what len() provides (1 or 2).
I have a list like this:
a = [(1,2,3,4), (2,3,2,2), (33,221,22,1) ...]
and I want to add for each item in the list a 5th value, for example:
new_a = [(1,2,3,4,"new"), (2,3,2,2,"new"), (33,221,22,1,"new") ...]
How can I do that because a.list or a.add freeze my computer.
for item in a:
a.add("new") or a.append("new")
The inner items are not lists, they are tuples. Tuples are immutable. Therefore, you probably need to create new tuples that contain the values you want:
new_a = [x + ('new',) for x in a]
This code iterates through all tuples present in a and for each one creates a new tuple consisting of the values of the original, plus the value 'new' (the value ('new',) is a tuple literal: it creates a new tuple with one value).
In the end, all the values created are assigned to the new list.
You can use map
>>> map(lambda x: x + ('new',), a)
[(1, 2, 3, 4, 'new'), (2, 3, 2, 2, 'new'), (33, 221, 22, 1, 'new')]
I'm following a couple of Pythone exercises and I'm stumped at this one.
# C. sort_last
# Given a list of non-empty tuples, return a list sorted in increasing
# order by the last element in each tuple.
# e.g. [(1, 7), (1, 3), (3, 4, 5), (2, 2)] yields
# [(2, 2), (1, 3), (3, 4, 5), (1, 7)]
# Hint: use a custom key= function to extract the last element form each tuple.
def sort_last(tuples):
# +++your code here+++
return
What is a Tuple? Do they mean a List of Lists?
The tuple is the simplest of Python's sequence types. You can think about it as an immutable (read-only) list:
>>> t = (1, 2, 3)
>>> print t[0]
1
>>> t[0] = 2
TypeError: tuple object does not support item assignment
Tuples can be turned into new lists by just passing them to list() (like any iterable), and any iterable can be turned into a new tuple by passing it to tuple():
>>> list(t)
[1, 2, 3]
>>> tuple(["hello", []])
("hello", [])
Hope this helps. Also see what the tutorial has to say about tuples.
Why are there separate tuple and list data types? (Python FAQ)
Python Tuples are Not Just Constant Lists
Understanding tuples vs. lists in Python
A tuple and a list is very similar. The main difference (as a user) is that a tuple is immutable (can't be modified)
In your example:
[(2, 2), (1, 3), (3, 4, 5), (1, 7)]
This is a list of tuples
[...] is the list
(2,2) is a tuple
A tuple is a sequence of immutable Python objects. Tuples are sequences, just like lists. The differences between tuples and lists are, the tuples cannot be changed unlike lists and tuples use parentheses, whereas lists use square brackets.
Creating a tuple is as simple as putting different comma-separated values. Optionally you can put these comma-separated values between parentheses also. For example −
tup1 = ('Dog', 'Cat', 2222, 555555);
tup2 = (10, 20, 30, 40, 50 );
tup3 = "a", "b", "c", "d";
The empty tuple is written as two parentheses containing nothing −
tup1 = ();
To write a tuple containing a single value you have to include a comma, even though there is only one value −
tup1 = (45,);
Like string indices, tuple indices start at 0, and they can be sliced, concatenated, and so on.
The best summary of the differences between lists and tuples I have read is this:
One common summary of these more interesting, if subtle, differences is that tuples are heterogeneous and lists are homogeneous. In other words: Tuples (generally) are sequences of different kinds of stuff, and you deal with the tuple as a coherent unit. Lists (generally) are sequences of the same kind of stuff, and you deal with the items individually.
From: http://news.e-scribe.com/397
Tuples are used to group related variables together. It's often more convenient to use a tuple rather than writing yet another single-use class. Granted, accessing their content by index is more obscure than a named member variable, but it's always possible to use 'tuple unpacking':
def returnTuple(a, b):
return (a, b)
a, b = returnTuple(1, 2)
In Python programming, a tuple is similar to a list. The difference between them is that we cannot change the elements of a tuple once it is assigned whereas in a list, elements can be changed.
data-types-in-python