我想从第一个元素相同的列表中删除元组,因为我将字母对视为具有相同的值,尽管它们有序。这是我试图迭代的列表,名为tuples2
:
[(3, 'A', 'C'), (3, 'C', 'A'), (2, 'B', 'C'), (2, 'C', 'B'), (1, 'A', 'B'), (1, 'B', 'A')]
我目前的代码:
for i in list(tuples2):
if i[0] == i+1[0]:
tuples2.remove(i)
print tuples2
......抛出这个错误:
line 6: if i[0] == (i+1)[0]: TypeError: can only concatenate tuple (not "int") to tuple
如果我想结束,我应该如何修改我的代码以解决这个问题
[(3, 'A', 'C'), (2, 'B', 'C'), (1, 'A', 'B')]
?
答案 0 :(得分:4)
此代码中有很多红旗。您不应该修改正在迭代的列表,这将导致您停止跳过项目。 编辑我现在看到您在for-loop中复制了列表,但是,以下方法更安全一点。您可以向后迭代,但构建新列表可能更容易。一种简单的方法是跟踪已经看到的第一个元素,并且只有在您之前看不到第一个元素时才添加:
In [1]: data = [(3, 'A', 'C'), (3, 'C', 'A'), (2, 'B', 'C'), (2, 'C', 'B'), (1, 'A', 'B'), (1, 'B', 'A')]
...:
In [2]: seen = set()
In [3]: new_data = []
...: for triple in data:
...: first = triple[0]
...: if first in seen:
...: continue
...: seen.add(first)
...: new_data.append(triple)
...:
In [4]: new_data
Out[4]: [(3, 'A', 'C'), (2, 'B', 'C'), (1, 'A', 'B')]
使用.remove
非常低效。它将您的算法更改为O(n ^ 2)而不是O(n)。
答案 1 :(得分:3)
你对i in list(tuples2)
的迭代有一个错误的概念:使用这种语法,我不是索引,而是实际上是元组本身。因此,您无法i+1[0]
。
首先,我建议你这样做:
tuples_list = list(tuples2)
要解决此问题,您可以使用python建议的xrange
(或range
),它将按索引工作:
for i in xrange(len(tuples_list)-1):
if tuples_list[i][0] == tuples_list[i+1][0]:
#Do what you want
答案 2 :(得分:3)
您可以读入由第一个组件键入的字典,然后读出值:
tuples = [(3, 'A', 'C'), (3, 'C', 'A'), (2, 'B', 'C'), (2, 'C', 'B'), (1, 'A', 'B'), (1, 'B', 'A')]
d = {x:(x,y,z) for x,y,z in tuples}
tuples = list(d.values())
结果tuples
:
[(1, 'B', 'A'), (2, 'C', 'B'), (3, 'C', 'A')]
答案 3 :(得分:2)
您可以使用groupby
模块中的itertools
解决您的问题:
from itertools import groubpy
a = [(3, 'A', 'C'), (3, 'C', 'A'), (2, 'B', 'C'), (2, 'C', 'B'), (1, 'A', 'B'), (1, 'B', 'A')]
final = [list(v)[0] for _,v in groupby(sorted(a), lambda x: x[0])]
print(final)
输出:
>>> [(1, 'A', 'B'), (2, 'B', 'C'), (3, 'A', 'C')]
否则,如果您需要的final
列表与您在问题中提供的顺序相同,则可以撤销该列表:
final = list(reversed(final))
# OR
#final = sorted(final, reverse = True)
print(final)
输出:
>>> [(3, 'A', 'C'), (2, 'B', 'C'), (1, 'A', 'B')]
答案 4 :(得分:2)
只需按第一个元素分组,然后取每组的第一个元素。
>>> [next(g) for _, g in itertools.groupby(tuples2, lambda x: x[0])]
[(3, 'A', 'C'), (2, 'B', 'C'), (1, 'A', 'B')]
甚至更简单:
>>> tuples2[::2]
[(3, 'A', 'C'), (2, 'B', 'C'), (1, 'A', 'B')]
答案 5 :(得分:1)
立即问题
这是什么意思?
i+1[0]
我是一个元组;您正尝试将 i 用作索引和元素。您需要的迭代更像是:
for i in range (len(tuples2)):
if tuples2[i] == tuples2[i+1]:
......仍然没有完成这项工作。这会检查整个元组的相等性。但是,你说你关心的只是第一个元素的相等。然后你会想要:
if tuples2[i][0] == tuples2[i+1][0]:
这是就你现在的代码而言;其他人向你展示了更多" Pythonic"这样做的方法。
一般解决方案
此代码假定元组的其他元素相等,具有相同第一元素的元组在列表中相邻,并且匹配元组仅成对出现。您的列表是否可能包含以下内容:
tuples2 = [(3, 'A', 'C'), (3, 'C', 'A'),
(2, 'B', 'C'), (2, 'C', 'B'),
(1, 'A', 'B'), (1, 'A', 'Z'), (1, 'B', 'A')]
附加' Z'元素可能被埋在" 3"元素?无论如何,即使您对列表进行排序,您也可以获得" AZ"另一个" 1"之间的元素元件。
如果这对您来说是个问题,那么我建议您先将每个元组转换为一个列表,然后将元素按顺序排序。例如,您可以将(1,' B' A' A')转换为[1,' A',' B&#39 ]。然后使用任何给定的方法来消除重复,包括您已编程的重复。我通常通过将事物重新转换为元组然后形成一组来自动消除重复。