Python中是否有元组数据结构?

5

我希望有一个包含标签、名称和值列表(数组)的三个项目组合,最好的数据结构是什么。

目前我正在使用字典,但它只允许两个项目,但可以轻松遍历。

for k, v in dict.iteritems():

我们能否有类似于以下的东西:

for k, v, x in tuple.iteritems():

5
问题标题有误导性;对于问题标题的答案是简单的“是”。实际上,问题的正文询问的是存储某些数据的最佳结构,这是一个不同的问题。 - Ben James
“最好的可能性”是没有意义的。请提出一个可以回答的问题。最适合什么目的?速度?存储?代码复杂度?什么? - S.Lott
有时候最好的选择是通用的,这意味着易用性、标准化、简单性,除非存在明显的性能问题或速度问题。 - Priyank Bolia
5个回答

8

Python数据结构教程请参阅第5.3节“元组和序列”。

但是,如果您想使用“name”作为索引来访问数据,则可能需要使用字典,将字符串名称作为键,其值为元组(tag, [value1, value2, ......]),例如:

  d = 
    { "foo" : ("dog", [1,2,3,4]),
      "bar" : ("cat", [4,5,6,7,8,9]),
      "moo" : ("cow", [4,5,7,8,9,1,3,4,65])
    }

  for name,(tag,values) in d.items():
    do_something()

这样,d["foo"]就能像其他字典一样正常运行了。

这是一个比被选中的答案更好的答案 - 它直接展示了解决所提出问题的方法。 - PaulMcG

4
为什么不使用元组列表(在Python中是一种数据类型,类似于列表,但不可变):
mylistoftuples = [(1, 2, 3), (2, "three", 4), (3, 4, [1, 2, 3, 4, 5])]
for k, v, x in mylistoftuples:
    print k, v, x

2
仅为完整起见,让我们注意到在项目查找部门中,这种方法失败得很厉害。 - Chris Lutz
1
我同意。请参考Kimvais的解决方案。 - Daren Thomas

4
您可以考虑使用collections.namedtuple类型来创建类似于元组的对象,这些对象可以通过属性查找访问字段。

collections.namedtuple(typename, field_names[, verbose])

返回一个名为typename的新元组子类。新子类用于创建类似于元组的对象,这些对象可通过属性查找访问字段,同时也是可索引和可迭代的。子类的实例还具有有用的docstring(带有typename和field_names)和有用的__repr__()方法,该方法以名称=值格式列出元组内容。

>>> import collections
>>> mytup = collections.namedtuple('mytup', ['tag','name', 'values'])
>>> e1 = mytup('tag1','great',[1,'two',3])
>>> e1
mytup(tag='tag1', name='great', values=[1, 'two', 3])
>>> e1.values
[1, 'two', 3]
>>> 

在其他答案的基础上,下面是过滤mytup对象列表的示例:

>>> tlist = [mytup("foo", "dog", [1,2,3,4]),
    mytup("bar","cat", [4,5,6,7,8,9]), mytup("moo","cow", [4,5,7,8,9,1,3,4,65])]
>>> tlist
[mytup(tag='foo', name='dog', values=[1, 2, 3, 4]),
mytup(tag='bar', name='cat', values=[4, 5, 6, 7, 8, 9]),
mytup(tag='moo', name='cow', values=[4, 5, 7, 8, 9, 1, 3, 4, 65])]
>>> [t for t in tlist if t.tag == 'bar']
[mytup(tag='bar', name='cat', values=[4, 5, 6, 7, 8, 9])]
>>> 
< p > Namedtuple 对象可以被用在其他结构中(例如一个 dict),正如其他答案中提到的那样。明显的优点是,这些字段是有名称的,使用它们的代码更加清晰。


如何创建一个这些命名元组的数组以便轻松遍历?很抱歉,我昨天刚开始学习Python,只是为了编写一个Python脚本。 - Priyank Bolia
添加了列表过滤示例。 - gimel
1
tlist = map(mytup, [("foo", "dog", [1,2]), ("bar", "cat", [3,4]),]) - jfs
1
@J.F. Sebastian,这是错误的,不起作用:TypeError: new()需要正好4个参数(已提供2个)。 - Priyank Bolia
@Priyank Bolia:正确。将map替换为itertools.starmap。请参见https://dev59.com/UkrSa4cB1Zd3GeqPXpvU#1842063。 - jfs

2

这里是一条评论,回复 @gimel的答案:

>>> import collections
>>> T = collections.namedtuple("T", 'tag name values')
>>> from itertools import starmap
>>> list(starmap(T, [("a", "b", [1,2]), ("c", "d",[3,4])]))
[T(tag='a', name='b', values=[1, 2]), T(tag='c', name='d', values=[3, 4])]

工作良好且编写简短,但不知为何我更喜欢吉米尔方法,它看起来更易于阅读,尽管需要更多的打字。 - Priyank Bolia

0

你可以拥有一个由三个元素组成的数组。

arr = [ (1,2,3), (4,5,6), (7,8,9)]
for (k, v, x) in arr:
  # do stuff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接