将 python 中的单个有序列表转换为字典

发布于 2024-08-09 17:19:20 字数 366 浏览 6 评论 0原文

我似乎找不到一种优雅的方式从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

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

I can't seem to find an elegant way to start from t and result in s.

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

Solutions I've come up with that seems less than elegant :

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

It's obviously easily solved, but, again, it seems like there's a better way. Is there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

策马西风 2024-08-16 17:19:20

我会使用 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),这是输入列表和当然是输出字典)。

docs 中建议的方法(每个人都应该熟悉该方法)页面(itertool Recipes)是该页面上的函数pairwise,这基本上是我在这里建议的第二个函数。我确实认为每个 site-packages 目录都应该包含一个包含这些配方的 iterutils.py 文件(可惜这样的文件还不是 python 的 stdlib 的一部分!-)。

I'd use itertools, but, if you think that's complicated (as you've hinted in a comment), then maybe:

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

d = dict(twobytwo(t))

or equivalently, and back to itertools again,

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

d = dict(twobytwo(t))

or, if you insist on being inline, in a season-appropriate "trick or treat" mood:

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

me, I consider this a trick, but some might find it a treat. IOW, I find this kind of thing scary, but apparently in the US around this time of the years things are supposed to be;-).

Basically, the problem boils down to "how do I walk a list 2 items at a time", because dict is quite happy to take a sequence of 2-tuples and make it into a dictionary. All the solutions I'm showing here ensure only O(1) extra space is taken (beyond the space, obviously O(N), that's needed for the input list and the output dict, of course).

The suggested approach in the docs (everybody should be familiar with that page, the itertool recipes) is the function pairwise on that page, which is basically the second one I suggested here. I do think every site-packages directory should contain an iterutils.py file with those recipes (pity such a file's not already a part of python's stdlib!-).

吻风 2024-08-16 17:19:20

Lukáš Lalinský 的答案相同,不同的习惯用法:

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

这使用 dictzipiter 函数。与 Lukáš 的答案相比,它的优势在于它适用于任何可迭代的对象。工作原理:

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

Same idea as Lukáš Lalinský's answer, different idiom:

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

This uses the dict, zip and iter functions. It's advantage over Lukáš' answer is that it works for any iterable. How it works:

  1. iter(t) creates an iterator over the list t.
  2. [iter(t)] * 2 creates a list with two elements, which reference the same iterator.
  3. zip is a function which take two iterable objects and pairs their elements: the first elements together, the second elements together, etc., until one iterable is exhausted.
  4. zip(*([iter(t)] * 2)) causes the same iterator over t to be passed as both arguments to zip. zip will thus take the first and second element of t and pair them up. And then the third and fourth. And then the fifth and sixth, etc.
  5. dict takes an iterable containing (key, value) pairs and creates a dctionary out of them.
  6. dict(zip(*([iter(t)] * 2))) creates the dictionary as requested by the OP.
苏佲洛 2024-08-16 17:19:20

不完全有效,但如果您不需要非常大的列表:

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

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

dict(t[i:i+2] for i in xrange(0, len(t), 2))

Not exactly efficient, but if you don't need it for very large lists:

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

Or your version using a generator:

dict(t[i:i+2] for i in xrange(0, len(t), 2))
无悔心 2024-08-16 17:19:20

伙计们,伙计们,使用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}

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

Guys, guys, use itertools. Your low-RAM users will thank you when the lists get large.

>>> 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}

It might not look pretty, but it won't make unnecessary in-memory copies.

随波逐流 2024-08-16 17:19:20

使用 stream 模块:

>>> 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,请不要走这条路;坚持标准库中的内容。

Using the stream module:

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

It should be noted that this module is fairly obscure and doesn't really "play by the rules" of what's typically considered politically correct Python. So if you are just learning Python, please don't go this route; stick to what's in the standard library.

如歌彻婉言 2024-08-16 17:19:20
dict(zip(t[::2], t[1::2]))

可能不是最有效的。适用于Python 3;你可能需要在 python 2.x 中导入 zip

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

probably not the most efficient. works in python 3; you might need to import zip, in python 2.x

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文