更好的方法来填充与字典其他元素相同编号的列表

时间:2019-05-20 22:40:02

标签: python dictionary

我正在处理以下格式的python字典:

y = {
    'column_a':[0,1,2],
    'column_b':[3,4,5],
    'column_c':[5,6,7]
}

其中dict的每个元素代表一个表的一列。因此,每一列必须具有相同数量的元素(等于表中的行数,这是我必须自己计算的值)。

我面临的问题是我需要添加另一列,并用单个值填充它。我目前正在写某种形式的

y['column_d'] = [some_value for i in range(len(y[y.keys()[0]]))]

至少在我看来,这是一个相当讨厌的词。 是否有一些更好/更优雅的方式来实现相同的性能(即不迭代列表本身)?

更具体地说,从字典中获取行数的更好方法是什么? IOW,有没有更好的书写方式

len(y[y.keys()[0]])

4 个答案:

答案 0 :(得分:2)

您只能手动对dict值使用“迭代”一次:

some_value = 1
y['column_d'] = [some_value] * len(next(iter(y.values()))) # python 3
y['column_d'] = [some_value] * len(next(y.itervalues()))   # python 2

或将dict_values强制转换为list(对于 python3 )并获取第一个元素:

y['column_d'] = [some_value] * len(list(y.values())[0])    # python 3
y['column_d'] = [some_value] * len(y.values()[0])          # python 2

更新。

有关@niCkcAMel答案的一些评论。 @ ChristianReall-Fluharty在评论中注意到,他选择此答案的原因之一是执行速度。我决定使用timeit对其进行测试。

两个答案中都提供3种方法。它们之间的区别在于长度的计算方法。因此,我已经完成了小型测试模块:

y = {
    'column_a': [0, 1, 2],
    'column_b': [3, 4, 5],
    'column_c': [5, 6, 7]
}
some_value = 1


def func(L):
    y['column_d'] = [some_value] * L


def function1():
    L = len(y[y.keys()[0]])            # -- Python 2
    # L = len(y[list(y.keys())[0]])    # -- Python 3
    func(L)


def function2():
    L = len(next(y.itervalues()))      # -- Python 2
    # L = len(next(iter(y.values())))  # -- Python 3
    func(L)


def function3():
    L = len(y.values()[0])             # -- Python 2
    # L = len(list(y.values())[0])     # -- Python 3
    func(L)


if __name__ == "__main__":
    import timeit
    print(timeit.timeit("function1()", setup="from __main__ import function1"))
    print(timeit.timeit("function2()", setup="from __main__ import function2"))
    print(timeit.timeit("function3()", setup="from __main__ import function3"))

所以,让我们启动测试。

  1. Python 2.7.16

    2.26870775476       # niCk cAMel      (3rd)
    2.14519973907       # Olvin Roght 1st (winner)
    2.1813173881        # Olvin Roght 2nd (2nd)
    
  2. Python 3.7.3

    2.396988793         # niCk cAMel      (3rd)
    2.175222899         # Olvin Roght 1st (winner)
    2.3292458960000006  # Olvin Roght 2nd (2nd)
    

结论:两种python版本的最快变体是使用itervalues() / iter()获取迭代器对象,并使用next()从迭代器获取下一个(第一项)

答案 1 :(得分:1)

是的...我也遇到过那些“讨厌”的词句..这是一个建议。

L = len(y[y.keys()[0]])
y['column_d'] = [some_value] * L

答案 2 :(得分:0)

您可以全面理解整个字典,而不必费心获取元素的大小(假设它与先前的行数不同步):

rowsToAdd    = 1
defaultValue = [0] * rowsToAdd  
y = { k:v + defaultValue for k,v in y.items() }

这是假定所有列都包含相同的数据类型,并希望使用相同的默认值。

如果每个列的默认值都不同,则可以使用每个列名称的默认值制作一个单独的字典,并在理解中使用它:

 defaults = {
     'column_a':[0],
     'column_b':['abc'],
     'column_c':[2.5]
     }
 rowsToAdd = 1
 y = { k:v + defaults[k]*rowsToAdd for k,v in y.items() }

答案 3 :(得分:0)

尝试以下解决方案,使用dict.values获取第一个键的值的长度,然后将其乘以完成:

y['column_d'] = [some_value] * len(list(y.values)[0])

现在:

print(y)

要使column_d的值重复正确的次数。