【问题标题】:optimizing frequency in a list of list, by each item's two first value通过每个项目的两个第一个值优化列表列表中的频率
【发布时间】:2017-10-14 07:02:05
【问题描述】:

我对编程完全陌生(不到 2 个月 - 自学),我正在做一个项目,它需要每个内部列表的前两个索引的列表列表频率。

这是我的清单:

x = [['block', 3], ['street', 2], ['lamp',1], ['street', 2], ['工业', 3], ['公园', 2], ['公园', 3], ['工业', 3], ['block', 3], ['street', 2], ['lamp',1], ['street', 2], ['industrial', 3], ['公园', 2]]

所以每个内部列表的第一个值是一个 TITLE,第二个是一个 CONVENTIONAL VALUE。

重要的是,您可以看到其中一些重复(重复)。

我想要一个这样的列表输出列表:


p = [['block', 3, 2], ['street', 2, 4], ['灯', 1, 2], ['工业', 3, 3], ['公园', 2, 2], ['公园', 3, 1]]

在外部列表 x 中,使用第三个值作为内部列表的频率。

所以这是我的非 Pythonic(可能是枯燥的)方法:


x = [['block', 3], ['street', 2], ['lamp',1], ['street', 2], ['industrial', 3], ['park', 2], ['park', 3], ['industrial', 3], ['block', 3], ['street', 2], ['lamp',1], ['street', 2], ['industrial', 3], ['park', 2]]
p = []

for a in x:
    p.append(a ),  a.append( x.count(a))

print p # checkpoint

i= 0
while i < len(p):
    for j in range(len(p)):
        if i == j:
            print i, ' = ', j
            break
        else:
            if p[i][:2] == p[j][:2]:
                print p[i][:2], '==', p[j][:2]
                p.pop(i)
                i = 0
                j=0
                break
    i = i+1

print p # the list of lists I'm desired

但是对于我的项目,因为这个函数后面跟着其他函数,与它们相比,这个函数的运行时间很长,尤其是对于大量输入数据集。

由于我缺乏知识,我无法优化我编写的代码。

所以我想问有没有更快、更 Python 的方式来做到这一点?

【问题讨论】:

    标签: python list duplicates frequency


    【解决方案1】:

    是的,使用字典。我假设顺序很重要,所以我将使用OrderedDict,但如果顺序无关紧要,您可以考虑使用Counter 对象:

    >>> from collections import OrderedDict
    >>> counter = OrderedDict()
    >>> for a, b in x:
    ...     t = (a, b)
    ...     counter[t] = counter.get(t, 0) + 1
    ...
    >>> final = [[a, b, v] for (a,b),v in counter.items()]
    >>> final
    [['block', 3, 2], ['street', 2, 4], ['lamp', 1, 2], ['industrial', 3, 3], ['park', 2, 2], ['park', 3, 1]]
    

    刚刚注意到您使用的是 Python 2(如果您能提供帮助,那么您真的应该使用 Python 3),在这种情况下,由于您使用的是 Python 2,因此您应该使用 counter.iteritems() 而不是 counter.items()

    比如:

    >>> final = [[a, b, count] for (a, b), count in counter.iteritems()]
    >>> final
    [['block', 3, 2], ['street', 2, 4], ['lamp', 1, 2], ['industrial', 3, 3], ['park', 2, 2], ['park', 3, 1]]
    

    注意,你的第一个 for 循环是二次缩放的,至于那个 while 循环,我不想考虑它,我想可能也是二次的,但可能更糟(因为你 .pop(i))但是我在上面发布的解决方案是线性扩展的。所以它应该能够有效地处理更大的数据集。

    【讨论】:

    • 感谢您的回答。代码是完美的。但是当我看到这个时,我不知道你是怎么做到的。我怎样才能提高我的思维编码能力,使其更像你的方法?这是必须时间来实现的吗?
    • @AfshinSalehi 大量练习并看到类似的问题。
    猜你喜欢
    • 2021-12-22
    • 2016-04-14
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多