1

我似乎找不到从t开始并导致s的优雅方式。

>>>t = ['a',2,'b',3,'c',4]
#magic
>>>print s
{'a': 2, 'c': 4, 'b': 3}

我提出的解决方案似乎不太优雅:

s = dict()
for i in xrange(0, len(t),2): s[t[i]]=t[i+1]
# or something fancy with slices that I haven't figured out yet

这显然很容易解决,但是,再次,似乎有更好的方法。有没有?

4

6 回答 6

10

我会使用itertools,但是,如果您认为这很复杂(正如您在评论中暗示的那样),那么也许:

def twobytwo(t):
  it = iter(t)
  for x in it:
    yield x, next(it)

d = dict(twobytwo(t))

或等效地,然后再次返回 itertools,

def twobytwo(t):
  a, b = itertools.tee(iter(t))
  next(b)
  return itertools.izip(a, b)

d = dict(twobytwo(t))

或者,如果您坚持要内联,则以适合季节的“不给糖就捣蛋”的心情:

d = dict((x, next(it)) for it in (iter(t),) for x in it)

我,我认为这是一种技巧,但有些人可能会觉得这是一种享受。IOW,我觉得这种事情很可怕,但显然在美国每年的这个时候事情应该是;-)。

基本上,问题归结为“我如何一次遍历一个列表 2 个项目”,因为dict很高兴将一个 2 元组序列放入字典中。我在这里展示的所有解决方案都确保只O(1)占用额外的空间(O(N)当然,除了空间之外,输入列表和输出字典需要这些空间)。

文档中建议的方法(每个人都应该熟悉该页面,itertool recipes)是pairwise该页面上的功能,这基本上是我在这里建议的第二个。我确实认为每个站点包目录都应该包含一个包含iterutils.py这些配方的文件(可惜这样的文件还不是 python 标准库的一部分!-)。

于 2009-10-29T02:03:12.737 回答
9

与Lukáš Lalinský 的回答相同的想法,不同的成语:

>>> dict(zip(*([iter(t)] * 2)))
{'a': 2, 'c': 4, 'b': 3}

这使用dict,zipiter函数。与 Lukáš 的回答相比,它的优势在于它适用于任何可迭代对象。这个怎么运作:

  1. iter(t)在 list 上创建一个迭代器t
  2. [iter(t)] * 2创建一个包含两个元素的列表,这两个元素引用相同的迭代器。
  3. zip是一个函数,它接受两个可迭代对象并将它们的元素配对:第一个元素在一起,第二个元素在一起等等,直到一个可迭代对象被耗尽。
  4. zip(*([iter(t)] * 2))导致相同的迭代器t作为两个参数传递给zip. zip因此将采用第一个和第二个元素t并将它们配对。然后是第三和第四。然后是第五和第六,等等。
  5. dict接受一个包含(key, value)对的可迭代对象并从中创建一个字典。
  6. dict(zip(*([iter(t)] * 2)))根据 OP 的要求创建字典。
于 2009-10-28T20:13:45.077 回答
7

效率不高,但如果您不需要它来处理非常大的列表:

dict(zip(t[::2], t[1::2]))

或者您使用生成器的版本:

dict(t[i:i+2] for i in xrange(0, len(t), 2))
于 2009-10-28T20:09:07.640 回答
6

伙计们,伙计们,使用 itertools。当列表变大时,您的低 RAM 用户会感谢您。

>>> from itertools import izip, islice
>>> t = ['a',2,'b',3,'c',4]
>>> s = dict(izip(islice(t, 0, None, 2), islice(t, 1, None, 2)))
>>> s
{'a': 2, 'c': 4, 'b': 3}

它可能看起来不漂亮,但它不会产生不必要的内存副本。

于 2009-10-28T20:17:21.230 回答
2

使用模块:

>>> from stream import chop
>>> t = ['a',2,'b',3,'c',4]
>>> s = t >> chop(2) >> dict
>>> s
{'a': 2, 'c': 4, 'b': 3}

应该注意的是,这个模块相当晦涩,并没有真正“遵守规则”,通常被认为是政治上正确的 Python。所以如果你只是学习 Python,请不要走这条路;坚持标准库中的内容。

于 2010-05-31T07:16:36.220 回答
1
dict(zip(t[::2], t[1::2]))

可能不是最有效的。在 python 3 中工作;您可能需要在 python 2.x 中导入 zip

于 2009-10-28T20:11:25.047 回答