当前位置: 首页 > 知识库问答 >
问题:

什么是Pythonic的方式来做下面的转换列表中的迪克斯?

索正豪
2023-03-14

我有一张这样的口述清单:

l = [{'name': 'foo', 'values': [1,2,3,4]}, {'name': 'bar', 'values': [5,6,7,8]}]

我想获得以下表格的输出:

>>> [('foo', 'bar'), ([1,2,3,4], [5,6,7,8])]

但是除了循环和追加之外,我看不到解决方案。还有比这样做更聪明的方法吗?

names = []
values = []
for d in l:
    names.append(d['name'])
    values.append(d['values'])

共有3个答案

白信鸿
2023-03-14

您可以使用操作符.itemgetter来保证值的顺序:

from operator import itemgetter

fields = ('name', 'values')
res = list(zip(*map(itemgetter(*fields), L)))

print(res)

[('foo', 'bar'), ([1, 2, 3, 4], [5, 6, 7, 8])]

如果假设Python 3.6,您不能保证字典在输入列表中的适当插入顺序,您将需要像上面那样显式定义顺序。

性能

虽然“元组理解”列表起作用,但当查询多个字段时,它变得不可读且效率低下:

from operator import itemgetter

n = 10**6
L = [{'name': 'foo', 'values': [1,2,3,4], 'name2': 'zoo', 'name3': 'xyz',
      'name4': 'def'}, {'name': 'bar', 'values': [5,6,7,8], 'name2': 'bart',
      'name3': 'abc', 'name4': 'ghi'}] * n

%timeit [tuple(k["name"] for k in L), tuple(k["values"] for k in L),\
         tuple(k["name2"] for k in L), tuple(k["name3"] for k in L),
         tuple(k["name4"] for k in L)]

%timeit fields = ('name', 'values', 'name2', 'name3' ,'name4');\
        list(zip(*map(itemgetter(*fields), L)))

1 loop, best of 3: 1.25 s per loop
1 loop, best of 3: 1.04 s per loop
蔡弘扬
2023-03-14

如果我写这段代码是为了公众消费,我会使用列表理解(很像eyllanesc的)。但为了好玩,这里有一个不使用任何s的单行程序

>>> l = [{'name': 'foo', 'values': [1,2,3,4]}, {'name': 'bar', 'values': [5,6,7,8]}]
>>> list(zip(*map(dict.values, l)))
[('foo', 'bar'), ([1, 2, 3, 4], [5, 6, 7, 8])]

(请注意,只有在字典保留插入顺序的情况下,这才可靠地工作,并非所有版本的Python都是如此。CPython 3.6将其作为一个实现细节,但从3.7开始,它仅是有保证的行为。)

流程的快速分解:

  • dict.values返回一个dict\u values对象,该对象是一个包含该dict的所有值的iterable。
  • map获取l中的每个字典,并调用其中的dict.values,返回dict\u values对象的iterable。
  • zip(*thing)是一个经典的“换位”方法,它采用了一个可替换的元素,并有效地沿对角线翻转。例如,[a,b],[c,d]]变成了[a,c],[b,d]]。这会将所有名称放入一个元组,将所有值放入另一个元组。
  • list将zip对象转换为列表
洪高阳
2023-03-14

使用生成器表达式:

l = [{'name': 'foo', 'values': [1,2,3,4]}, {'name': 'bar', 'values': [5,6,7,8]}]
v = [tuple(k["name"] for k in l), tuple(k["values"] for k in l)]
print(v)

输出:

[('foo', 'bar'), ([1, 2, 3, 4], [5, 6, 7, 8])]
 类似资料:
  • 问题内容: 我有一个Python脚本,该脚本接受一个整数列表作为输入,我需要一次使用四个整数。不幸的是,我无法控制输入,或者将其作为四元素元组的列表传递。目前,我正在以这种方式对其进行迭代: 不过,它看起来很像“ C思维”,这使我怀疑还有一种处理这种情况的更Python的方法。列表在迭代后被丢弃,因此不需要保留。也许像这样会更好? 不过,还是不太“正确”。 问题答案: 从Python的iterto

  • 问题内容: 我有一个函数,其输入参数可以是一个元素或元素列表。如果此参数是单个元素,则将其放在列表中,以便可以以一致的方式遍历输入。 目前我有这个: 我正在使用现有的API,因此无法更改输入参数。使用isinstance()感觉很麻烦,所以有 适当的 方法吗? 问题答案: 我喜欢Andrei Vajna的建议。请注意以下一些典型的Python类型的结果: 这具有将字符串视为不可重复的额外优势-字符

  • 问题内容: 我有一个Python脚本,该脚本接受一个整数列表作为输入,我需要一次处理四个整数。不幸的是,我无法控制输入,或者将其作为四元素元组的列表传递。目前,我正在以这种方式对其进行迭代: 不过,这看起来很像“C-think”,这让我怀疑有一种更像蟒蛇的方式来处理这种情况。列表在迭代后被丢弃,因此不需要保留它。也许这样更好? 不过,仍然感觉不太正确。 问题答案: 从Python的itertool

  • 表达式--a^b^c^d。 什么将是它的后缀表达式。 如果遇到具有从右到左关联性的运算符,我们该怎么办?我们是将其推入堆栈还是将其弹出?

  • 我是一个使用Hibernate的新手,我正在编写一个简单的方法来返回匹配特定过滤器的对象列表。似乎是一种自然的返回类型。 我注意到确实声明了一个;但它完全是一种不同的类型-作为原始类型返回。我觉得奇怪的是,最近的Hibernate(4.0.x)没有实现参数化类型,所以我怀疑是我做错了什么。 它看起来非常像将Hibernate结果转换为对象列表,但这里没有“硬”错误(系统知道类型Foo,我使用的不是

  • 问题内容: 我有两个列表,一个被命名为A,另一个被命名为B。A中的每个元素都是一个三元组,B中的每个元素只是一个数字。我想计算定义为的结果: 结果= A [0] [0] * B [0] + A [1] [0] * B [1] + … + A [n-1] [0] * B [n-1] 我知道逻辑很简单,但是如何以pythonic方式编写呢? 谢谢! 问题答案: http://docs.scipy.or