I have a list of tuples, with each tuple containing a tuple pair, coordinates.
list1 = [((11, 11), (12, 12)), ((21, 21), (22, 22)), ((31, 31), (32, 32))]
Using list comprehension I am trying to generate a list without them being paired but still in the same order.
I was able to get the result be looping and using .append() but I was trying to avoid this.
new_list = []
for i in list1:
for x in i:
new_list.append(x)
print(new_list)
this works and gives me the result I am looking for:
[(11, 11), (12, 12), (21, 21), (22, 22), (31, 31), (32, 32)]
But when I try list comprehension I get the last tuple pair repeated!
new_list = [x for x in i for i in list1]
print(new_list)
[(31, 31), (31, 31), (31, 31), (32, 32), (32, 32), (32, 32)]
I am sure it is a small thing I am doing wrong so would appreciate the help!!
try :
print([inner_tuple for outer_tuple in list1 for inner_tuple in outer_tuple])
Nested fors should come to the right side. for sub in list1 after that for x in sub.
And btw, you didn't get NameError: name 'i' is not defined because, you wrote that list-comprehension after the for loop. In that time i is a global variable and exists.
The execution of the loop is out-inner type
Your code misses is close but it takes x only
Your code:
new_list = []
for i in list1:
for x in i:
new_list.append(x)
which is equivalent to
new_list = [x for i in list1 for x in i]
So, now you can understand the variables how they are taking values from for loops
Related
I have a list of tuples that starts out empty and is appended with new user-generated tuples.
if left_mouse == True:
generic_list.append((mouse_position_x, mouse_position_y))
To prevent having multiple tuples with the same (x, y) data, I want to iterate through the list and check if the newest tuple is the same as any other tuple in the list, and if it is, replace the old tuple with the new one.
for tuple in tuple_list:
if tuple_list[-1].position == tuple_list[i].position:
tuple_list.remove(i)
I know what I've got is wrong, but I don't know why or how to move forward. Any help would be really appreciated.
Edit: I'm now using set() and it works perfectly. Thanks everyone.
i recommend using a set (instead of a list):
>>> d = {tuple(RND.sample(range(100), 2)) for c in range(5)}
>>> d
{(17, 53), (74, 5), (88, 11), (21, 56), (15, 78)}
>>> type(d)
<class 'set'>
>>> a = (15, 78)
>>> a in d
True
>>> b = (32, 6)
>>> b in d
False
>>> d.add((4, 1))
>>> d
{(74, 5), (15, 78), (17, 53), (88, 11), (4, 1), (21, 56)}
To your specific question: You are iterating over your tuple_list with a variable called tuple. That's what you should use to compare against:
last_tuple = tuple_list[-1]
for tuple in tuple_list[:-1]:
if tuple.position == last_tuple.position:
tuple_list.remove(tuple)
Except you should not do that at all, because you're doing all kinds of extra work. Instead, maintain a set in parallel with your tuple list, and use the set to determine whether you have seen the position before.
(This assumes your list is hundreds or thousands of elements long. If you're only tracking three or four positions, you could just lsearch the list.)
generic_list = []
positions_seen = set(generic_list)
# blah blah blah code
if left_mouse:
pos = (mouse_position_x, mouse_position_y)
if pos not in positions_seen:
positions_seen.add(pos)
generic_list.append(pos)
If order doesn't matter, you could use a set. It'll keep only unique tuple in your list. Then you can create a new list from this set if needed. For example:
generic_list = [(1,2), (3,4), (1,2), (5,6)]
generic_list = set(generic_list) # {(1, 2), (3, 4), (5, 6)}
generic_list = list(generic_list) # [(1, 2), (5, 6), (3, 4)]
I am trying to find duplicates within tuples that are nested within a list. This whole construction is a list too. If there are other better ways to organize this to let my problem to be solved - I'd be glad to know, because this is something I build on the way.
pairsList = [
[1, (11, 12), (13, 14)], #list1
[2, (21, 22), (23, 24)], #list2
[3, (31, 32), (13, 14)], #list3
[4, (43, 44), (21, 22)], #list4
]
The first element in each list uniquely identifies each list.
From this object pairsList, I want to find out which lists have identical tuples. So I want to report that list1 has the same tuple as list3 (because both have (13,14). Likewise, list2 and list4 have the same tuple (both have (21,22)) and need to be reported. The position of tuples within the list doesn't matter (list2 and list4 both have (13,14) even though the position in the list the tuple has is different).
The output result could be anything iterable later on such as (1,3),(2,4) or [1,3],[2,4]. It is the pairs I am interested in.
I am aware of sets and have used them to delete duplicates within the lists in other situations, but cannot understand how to solve this problem. I can check like this if one list contains any element from the other list:
list1 = [1, (11, 12), (13, 14)]
list2 = [3, (31, 32), (13, 14)]
print not set(list1).isdisjoint(list2)
>>>True
So, the code below lets me know what lists have same tuple(s) as the first one. But what is the correct way to perform this on all the lists?
counter = 0
for pair in pairsList:
list0 = pairsList[0]
iterList = pairsList[counter]
if not set(list0).isdisjoint(iterList):
print iterList[0] #print list ID
counter += 1
The first element in each list uniquely identifies each list.
Great, then let's convert it to a dict first:
d = {x[0]: x[1:] for x in pairsList}
# d:
{1: [(11, 12), (13, 14)],
2: [(21, 22), (23, 24)],
3: [(31, 32), (13, 14)],
4: [(43, 44), (21, 22)]}
Let's index the whole data structure:
index = {}
for k, vv in d.iteritems():
for v in vv:
index.setdefault(v, []).append(k)
Now index is:
{(11, 12): [1],
(13, 14): [1, 3],
(21, 22): [2, 4],
(23, 24): [2],
(31, 32): [3],
(43, 44): [4]}
The output result could be anything iterable later on such as (1,3),(2,4) or [1,3],[2,4]. It is the pairs I am interested in.
pairs = [v for v in index.itervalues() if len(v) == 2]
returns [[1,3],[2,4]].
I have a list
List1 = [(12,34),(12,6),(2,4),(1,3),(34,32),(34,6)]
and another list
List2 = [(12,34),(12,6),(2,4),(1,3),(34,32),(56,12),(78,23),(23,56)]
I want to create a new list, check the elements of the first against the elements of the second. Editing the second list basically. This list would become
List3 = [(56,12),(78,23),(23,56)]
If order/duplicates don't matter:
>>> A = [(12,34),(12,6),(2,4),(1,3),(34,32),(34,6)]
>>> B = [(12,34),(12,6),(2,4),(1,3),(34,32),(56,12),(78,23),(23,56)]
>>> set(B).difference(A)
set([(78, 23), (56, 12), (23, 56)])
Otherwise, if order does matter, just use a list comprehension check membership of a set (O(1) amortized membership checks):
>>> set_A = set(A)
>>> [x for x in B if x not in set_A]
[(56, 12), (78, 23), (23, 56)]
Keep in mind that this simple solution also works:
>>> [x for x in B if x not in A]
[(56, 12), (78, 23), (23, 56)]
It will just have to potentially scan through the entire list A every time it checks x not in A.
Say I have a list:
[(12,34,1),(123,34,1),(21,23,1)]
I want to remove the 1 from each tuple in the list so it becomes
[(12,34),(123,34),(21,23)]
You want to truncate your tuples, use a list comprehension:
[t[:-1] for t in listoftuples]
or, as a simple demonstration:
>>> listoftuples = [(12,34,1),(123,34,1),(21,23,1)]
>>> [t[:-1] for t in listoftuples]
[(12, 34), (123, 34), (21, 23)]
Tuples are immutable, so you can not remove an item. However, you can create a new tuple from the old tuple not including the elements you do not want to. So, to delete an arbitrary item from each tuple from a list of tuples, you can do:
def deleteItem(lst, toDel):
return [tuple(x for x in y if x != toDel) for y in lst]
Result:
>>> lst = [(12,34,1),(123,34,1),(21,23,1)]
>>> deleteItem(lst, 1)
[(12, 34), (123, 34), (21, 23)]
>>> a=[(12, 34, 1), (123, 34, 1), (21, 23, 1)]
>>> [filter (lambda a: a != 1, x) for x in a]
[(12, 34), (123, 34), (21, 23)]
THis will remove all 1 from the tuple irrespective of index
Since you can't change tuples (as they are immutable), I suggest using a list of lists:
my_list = [[12,34,1],[123,34,1],[21,23,1]]
for i in my_list:
i.remove(1)
return my_list
This returns: [[12, 34], [123, 34], [21, 21]].
python 3.2
1. [(i,v)for i,v,c in list1]
2. list(map(lambda x:x[:2],list1))
I need a list like this:
[(16,2), (14,3), (15,3), (16,3), (18,3), (19,3), (12,4), (13,4), (14,4)]
But much, much longer. There are certain really large range patterns in this list, but also irregularities. So it would be unfeasible to write down all tuples, but I can't make a simple listcomp either.
I wanted to use:
[(16,2), (x,3) for x in range(14,19), (x,4) for x in range(12,14)]
But according to the docs, [x, y for ...] is not allowed, and my example is interpreted as an unparenthesed tuple of 2 parenthesed tuples, instead of a tuple followed by a list comprehension.
Any solutions?
Try this:
[(16, 2)] + [(x,3) for x in range(14,19)] + [(x,4) for x in range(12,14)]
From your question is not clear if you're trying to increase the second index at every new range.
If that's the case you could put all the ranges in a list and use itertools.count():
from itertools import count
indexes = [(16,17), (14, 20), (12, 15)]
[(x, n) for i,n in zip(indexes,count(2)) for x in range(*i)]
Which give exactly:
[(16, 2), (14, 3), (15, 3), (16, 3), (17, 3), (18, 3), (19, 3), (12, 4), (13, 4), (14, 4)]
You could create separate lists and then append them to each other.
a = [(16, 2)]
b = [(x, 3) for x in range(14, 19)]
c = [(x, 4) for x in range(12, 15)]
a.extend(b)
a.extend(c)