首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >大多数pythonic3解压(?)实现

大多数pythonic3解压(?)实现
EN

Stack Overflow用户
提问于 2016-04-08 17:44:33
回答 3查看 48关注 0票数 1

(“解压缩”显然是一个不好的名字,但我不确定哪个才是正确的。如果这意味着我由于不知道要搜索什么而错过了权威答案,请原谅。)

假设我们有

代码语言:javascript
复制
people = [
    (1, 'anne'),
    (2, 'ben'),
    (3, 'charlie'),
]

( django中常见的选项等)

现在我们需要一个“键”列表或第一个元素的列表:[1, 2, 3]

在python 3中,我使用

代码语言:javascript
复制
people_ids, _ = list(zip(*people))
# or even
people_ids = [p[0] for p in people]

zip的方式看起来并不是很整洁,特别是Python3需要额外的list(...)来使zip成为迭代器。

第二种理解方法更具可读性,但不能一概而论,例如。在同一次调用中返回第二个、第三个元素等的列表。

有没有更好的方法?

(其中“更好”主要是指干净和可读,但性能也可能有一些可观的)

EN

回答 3

Stack Overflow用户

发布于 2016-04-08 17:58:03

使用next,您可以从迭代器中获取第一项:

代码语言:javascript
复制
>>> people = [
...     (1, 'anne'),
...     (2, 'ben'),
...     (3, 'charlie'),
... ]
>>> next(zip(*people))
(1, 2, 3)

operator.itemgetter使用map的替代方案

代码语言:javascript
复制
>>> import operator
>>> list(map(operator.itemgetter(0), people))
[1, 2, 3]

顺便说一句,没有listzip解决方案应该可以工作:

代码语言:javascript
复制
>>> people_ids, _ = zip(*people)
>>> people_ids
(1, 2, 3)
票数 2
EN

Stack Overflow用户

发布于 2016-04-08 18:09:02

对于特定的示例,您可以稍微“滥用”一下dict

代码语言:javascript
复制
people = [
    (1, 'anne'),
    (2, 'ben'),
    (3, 'charlie'),
]

d_people = dict(people)

然后你就有了一个很好的数据模型。这有一些问题:键不能重复,并且不能处理具有两个以上元素的元组。但是对于这种情况(这是非常典型的!)效果非常好。

然后,您可以通过执行keys命令来简单地获取密钥

代码语言:javascript
复制
d_people.keys()

或者,显式列表:

代码语言:javascript
复制
list(d_people)
list(d_people.keys())

它们是等价的。

票数 0
EN

Stack Overflow用户

发布于 2016-04-08 18:12:35

获取基于ids的子集可以由operator.itemgetter完成。可以通过创建显式切片对象并将其传递给函数来获得压缩后的值的子切片。

代码语言:javascript
复制
import operator

people = [
    (1, 'anne', 'some'),
    (2, 'ben', 'another'),
    (3, 'charlie', 'field'),
]

people_ids = [p[0] for p in people]  # 0 may be passed as funtion argument
people_ids_and_another = [operator.itemgetter(*[0, 2])(p) for p in people]  # [0, 2] may be passed as function argument
people_ids_and_name_via_slice = [p[slice(0,2,None)] for p in people]  # equal to p[0:2], but passable as argument

要演示函数用法,请执行以下操作:

代码语言:javascript
复制
def dezip(seq, what):
    if isinstance(what, list):
        return [operator.itemgetter(*what)(p) for p in people]
    else:
        return [p[what] for p in people]

assert dezip(people, slice(0,2,None)) == [(1, 'anne'), (2, 'ben'), (3, 'charlie')]
assert dezip(people, 0) == [1, 2, 3]
assert dezip(people, [0, 2]) == [(1, 'some'), (2, 'another'), (3, 'field')]

如果你要去掉'list of in‘的要求,你可以去掉函数体中的If语句。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36496439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档