在元组列表中,如果元组[0]与列表中的另一个元组[0]重复,则返回元组[1]

时间:2014-10-16 01:01:28

标签: python list collections tuples duplicate-removal

我有一个由包含2个字符串的元组组成的列表 第一个是校验和,第二个是相应文件的名称 有没有快速的方法来搜索重复的校验和并返回相应的文件名?

例如:

[("sumstring1","abc.txt"),("sumstring2","def.txt"),("sumstring1","ghi.txt"),("sumstring2","jkl.txt")]
-->
    [("abc.txt","ghi.txt"),("def.txt","jkl.txt")]

我尝试制作两个不同的列表,一个是cheksums,另一个是文件名。 然后我使用collections.Counter来查找重复的校验和。使用list.index()我从其他列表中获取了索引和相应的文件名,如下所示:

csList=["sumstring1","sumstring2","sumstring1","sumstring2"]
fnList=["abc.txt","def.txt","ghi.txt","jkl.txt"]
indexList=[]

multiList=[(k,v) for k,v in collections.Counter(csList).items() if v>1]

(在这种情况下,multiList将为[("sumstring1",2),("sumstring2",2)]

for elem in multiList:
    temp=()
    for i in range(elem[1]):
        temp+=(csList.index(elem[0]),)
        csList.remove(elem[0])
    indexList.append(temp)

这给了我一个列表,其中包含重复文件([(0,2),(1,3)])的索引,然后我可以使用它来查找文件名。

这很有效,但非常难看。是否有一个更简单,更多" python"这样做的方法?

3 个答案:

答案 0 :(得分:1)

您几乎不想在列表中使用index。迭代时跟踪你的位置;不要试图从价值中再次找到你的位置。

在这种情况下,你真正想要的是一个" multidict",一个将键映射到值集合的字典。在这种情况下,校验和到名称集合。然后,任何映射到一组多于一个名称的校验和,它都是双重的,并且该集合恰好是您要打印出来的名称列表,所以它只需要。

在Python中,multidict通常表示为dict,其值为列表或集合。您可以使用元组,正如您尝试的那样,它将工作 - 但从概念上讲,它们通常代表固定长度的异构值集合,其中a的索引值告诉你它的含义。我们这里有任意长度。同质的价值集合,其中指数毫无意义,甚至订单也毫无意义。这是一套,而不是一个元组。 (如果订单没有意义,那么它可以是列表,也可以是OrderedSet。)

例如:

>>> pairs = [("sumstring1","abc.txt"), ("sumstring2","def.txt"),
...          ("sumstring1","ghi.txt"), ("sumstring2","jkl.txt")]
>>> dups = collections.defaultdict(set)
>>> for checksum, name in pairs:
...     dups[checksum].add(name)
>>> dups
defaultdict(<class 'set'>, {'sumstring1': {'ghi.txt', 'abc.txt'}, 'sumstring2': {'def.txt', 'jkl.txt'}})

消除任何非重复:

>>> dups = {checksum: names for checksum, names in dups.items() if len(names) > 1}
>>> dups
{'sumstring1': {'abc.txt', 'ghi.txt'}, 'sumstring2': {'def.txt', 'jkl.txt'}}

(当然我们在你的例子中没有任何非重复内容,所以这并不令人兴奋)。

如果您不关心校验和,只需要一组集合:

>>> dups = list(dups.values())

如果由于某种原因你真的想要元组而不是集合:

>>> dups = [tuple(names) for names in dups.values()]
>>> dups
[('ghi.txt', 'abc.txt'), ('def.txt', 'jkl.txt')]

答案 1 :(得分:0)

你想要的是dictionary。这将为您提供即时查找时间,并将消除重复的密钥。

d = {}
d['sumstring1'] = 'abc.txt'
d.get('sumstring1')
>>> 'abc.txt'
d['sumstring1']
>>> 'abc.txt'

您无法两次添加密钥,因此如果您执行以下操作:

d['sumstring1'] = 'def.txt'

您将使用新值替换旧值。

要记录多个结果,您只需将列表存储在字典列表中即可:

d['sumstring2'] = ['ghi.txt', 'jkl.txt']

答案 2 :(得分:0)

你可以使用字典。

tuples = [("sumstring1","abc.txt"),("sumstring2","def.txt"),("sumstring1","ghi.txt"),("sumstring2","jkl.txt")]

lookup = {}
for checksum, filename in tuples:
    lookup.setdefault(checksum, []).append(filename)

for checksum, filenames in lookup.items():
    if len(filenames) >= 2:
        print(checksum, filenames)

输出

sumstring1 ['abc.txt', 'ghi.txt']
sumstring2 ['def.txt', 'jkl.txt']