【问题标题】:python create a set / dict / list and the sum of its values from a single list comprehensionpython从单个列表理解中创建一个集合/字典/列表及其值的总和
【发布时间】:2013-10-21 19:40:24
【问题描述】:

我想知道是否需要两个列表推导来返回 set / dict / list 的有序对以及 set / dict / list 中的值的总和。这是我的意思的一个例子:

>>> l = ['abc', 'd', 'efgh', 'ij']
>>> {i: len(i) for i in l}, sum(len(i) for i in l)
({'efgh': 4, 'abc': 3, 'ij': 2, 'd': 1}, 10)

有没有比重复的 for i in l 理解更好/更 Pythonic 的方式来写这个?

更新:

我问这个问题是因为我在想最好的方法来写一个特定的lambda;即

>>> l = ['abc', 'd', 'efgh', 'ij']
>>> dict_value = lambda l: ({i: len(i) for i in l}, sum(len(i) for i in l))
>>> dict_value(l)
({'efgh': 4, 'abc': 3, 'ij': 2, 'd': 1}, 10)

我问这个问题是因为我没有使用len() 来计算我想要的值,而是一个昂贵的计算。如果我定义辅助方法而不是 lambda 来工作,下面关于 for 循环的点确实解决了问题。

【问题讨论】:

    标签: python list-comprehension


    【解决方案1】:

    您可以预先计算长度。我认为看起来更干净:

    >>> l = ['abc', 'd', 'efgh', 'ij']
    >>> llen = [len(i) for i in l]
    >>> dict(zip(l,llen)), sum(llen)
    ({'abc': 3, 'd': 1, 'efgh': 4, 'ij': 2}, 10)
    

    【讨论】:

    • 请注意,字符串长度只是对字符串的简单属性查找;这不会给你带来太多的速度。
    • 我知道,但我不认为 OP 真的在寻找速度。实际上,这些天我大部分时间都不明白人们所说的“pythonic”方式是什么意思。我认为他们通常只是在寻找更短或更简洁的代码,不管幕后发生了什么。
    • @HariShankar Re: 'more pythonic' .. 我明白你的意思。我认为速度是答案的很大一部分。任何人都不应该在他们的代码中编写一些可读性吗?
    • 我同意,在大多数情况下,可读性应该是第一要务。但问题是它通常是主观的。
    【解决方案2】:

    是的,或者您只是使用常规循环:

    d, s = {}, 0
    for i in l:
        d[i] = len(i)
        s += len(i)
    

    应该使用列表或集合或字典理解来创建一个对象;避免尝试产生副作用。并且不要低估常规循环的实用性!

    另外,不要犹豫,使用函数而不是 lambda:

    def as_dict_and_total(l):
        d, s = {}, 0
        for i in l:
            d[i] = len(i)
            s += len(i)
        return d, s
    

    【讨论】:

    • 这个问题是它没有利用列表解析的速度,这比常规循环快得多。
    • @qaphla:没有那么快很多,一个循环比2个更好。
    • 我运行的大多数测试给出的列表推导速度是标准循环的两倍以上,但我确信这会因操作而异,因此不会争论这一点。跨度>
    • @Martijn 这是真的。但这不是列表理解,只是 for 循环。
    • @qaphla:这完全取决于你在做什么。大部分时间用于调整列表对象大小和.append() 属性查找。在一定程度上,两者都可以解决。
    猜你喜欢
    • 1970-01-01
    • 2022-06-27
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多