【问题标题】:Iterate over a list that contain duplicate elements遍历包含重复元素的列表
【发布时间】:2013-05-26 12:48:46
【问题描述】:

我正在尝试迭代一个包含一些重复元素的列表。我正在使用重复的数量,因此我不想在迭代列表之前将列表放入一个集合中。

我正在尝试计算元素出现的次数,然后写下元素(名称)和出现次数的计数。

我遇到的问题是,在我的输出 CSV 文件中,行数与元素出现的次数一样多。我在完成后将 CSV 写入 HTML 表,因此我希望对其进行重复数据删除。

我的最终目标是计算名称出现的次数,然后在包含名称和计数的 CSV 文件中写入一行,然后移至列表中的下一个名称。

我尝试搜索并遇到了itertools.groupby,但我不确定这在这种情况下是否有用,如果有用,如何正确使用它。

感谢您的帮助。

编辑:我忘了提 - Python 2.6

with open(sys.argv[1]) as infile:
    rdr = csv.DictReader(infile, dialect='excel')
    qualsin = []
    headers = ['Qualifier Name','Appointments']
    for row in rdr:
        row['Qualifier Name'] = row['Qualifier Name'].upper()
        qualsin.append(row['Qualifier Name'])
    qualsin.sort()
    #total = 0
    with open('tempwork.csv', 'w') as tempwork:
        wrtr = csv.writer(tempwork, dialect='excel')
        wrtr.writerow(headers)
        for quals in qualsin:
            d = [quals, qualsin.count(quals)]
            #a = dict((key, value) for (key, value) in d)
            #total += qualsin.count(quals)
            wrtr.writerow(d)

【问题讨论】:

标签: python csv for-loop deduplication


【解决方案1】:

您可以在一组其他名称中提取,然后使用原始列表进行计数。

例如,给定qualsin = [0, 2, 3, 2, 3, 1, 2, 3, 5, 3, 3, 2, 4]

set_quals = set(qualsin) # This is set([0, 1, 2, 3, 4, 5])
for quals in set_quals: # Iterate over the values in the set, not the list
    d = [quals, qualsin.count(quals) # count the values from the list, not the set
    wrtr.writerow(d)

或者……

import collections

...
set_quals = set(qualsin) # This is set([0, 1, 2, 3, 4, 5])
counts = collections.Counter(qualsin) # This is Counter({3: 5, 2: 4, 0: 1, 1: 1, 4: 1, 5: 1}) which acts like a dictionary
for quals in set_quals:
    d = [quals, counts[quals]] # use the name from the set and the value from the Counter
    wrtr.writerow(d)

编辑
由于您使用 Python2.6 的更新,Counter 不可用。但是,第一个解决方案仍然有效。

你可以自己做一个计数器:

counts = collections.defaultdict(int) # Available since 2.5
for quals in qualsin:
    counts[quals] += 1

如果我没记错的话,使用计数器(无论是在 2.7 中还是像上面那样自制)都会将时间复杂度降低 N 倍。 list.count 是 O(N),你在循环中这样做,所以你得到 O(N^2)。创建计数器的单次迭代只需 O(N),因此对于较大的列表,这可能会有很大帮助。

编辑 2

要获得按字母顺序排序的输出,您只需将重复数据删除列表(集合)转换回排序列表。

ordered_deduped_quals = sorted(set(qualsin))
for quals in ordered_deduped_quals:
    ...

【讨论】:

  • 非常感谢!我现在将使用您的第一个示例来试一试。
  • 非常感谢您的帮助!希望我能投票给答案。这正是我所需要的。唯一剩下的就是在写入之前对其进行排序。我理解一组它没有排序。你知道我能不能在写之前把它放回一个列表并排序?
  • 第一次出现的顺序?
  • 字母顺序(它是用于报告目的的名称列表)
  • 查看EDIT 2了解如何操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 2019-10-06
相关资源
最近更新 更多