标签归档:tuples

在Python中将列表转换为元组

问题:在Python中将列表转换为元组

我正在尝试将列表转换为元组。

Google上的大多数解决方案都提供以下代码:

l = [4,5,6]
tuple(l)

但是,运行该代码会导致错误消息:

TypeError:“元组”对象不可调用如何解决此问题?

I’m trying to convert a list to a tuple.

Most solutions on Google offer the following code:

l = [4,5,6]
tuple(l)

However, the code results in an error message when I run it:

TypeError: ‘tuple’ object is not callable How can I fix this problem?


回答 0

它应该工作正常。不要使用tuplelist或其他特殊的名字作为变量名。这可能是导致您出现问题的原因。

>>> l = [4,5,6]
>>> tuple(l)
(4, 5, 6)

It should work fine. Don’t use tuple, list or other special names as a variable name. It’s probably what’s causing your problem.

>>> l = [4,5,6]
>>> tuple(l)
(4, 5, 6)

回答 1

扩展eumiro的注释,通常tuple(l)会将列表l转换为元组:

In [1]: l = [4,5,6]

In [2]: tuple
Out[2]: <type 'tuple'>

In [3]: tuple(l)
Out[3]: (4, 5, 6)

但是,如果您已重新定义tuple为元组而不是type tuple

In [4]: tuple = tuple(l)

In [5]: tuple
Out[5]: (4, 5, 6)

那么您会收到TypeError,因为元组本身不可调用:

In [6]: tuple(l)
TypeError: 'tuple' object is not callable

您可以tuple通过退出并重新启动解释器来恢复原始定义,或者(感谢@glglgl):

In [6]: del tuple

In [7]: tuple
Out[7]: <type 'tuple'>

Expanding on eumiro’s comment, normally tuple(l) will convert a list l into a tuple:

In [1]: l = [4,5,6]

In [2]: tuple
Out[2]: <type 'tuple'>

In [3]: tuple(l)
Out[3]: (4, 5, 6)

However, if you’ve redefined tuple to be a tuple rather than the type tuple:

In [4]: tuple = tuple(l)

In [5]: tuple
Out[5]: (4, 5, 6)

then you get a TypeError since the tuple itself is not callable:

In [6]: tuple(l)
TypeError: 'tuple' object is not callable

You can recover the original definition for tuple by quitting and restarting your interpreter, or (thanks to @glglgl):

In [6]: del tuple

In [7]: tuple
Out[7]: <type 'tuple'>

回答 2

您可能已经做过这样的事情:

>>> tuple = 45, 34  # You used `tuple` as a variable here
>>> tuple
(45, 34)
>>> l = [4, 5, 6]
>>> tuple(l)   # Will try to invoke the variable `tuple` rather than tuple type.

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    tuple(l)
TypeError: 'tuple' object is not callable
>>>
>>> del tuple  # You can delete the object tuple created earlier to make it work
>>> tuple(l)
(4, 5, 6)

这是问题所在…由于您使用了tuple变量来保存tuple (45, 34)较早的内容…所以,现在tupleobject类型tuple

它不再是一个type,因此不再Callable

Never使用任何内置类型作为变量名…您确实可以使用任何其他名称。请为变量使用任意名称…

You might have done something like this:

>>> tuple = 45, 34  # You used `tuple` as a variable here
>>> tuple
(45, 34)
>>> l = [4, 5, 6]
>>> tuple(l)   # Will try to invoke the variable `tuple` rather than tuple type.

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    tuple(l)
TypeError: 'tuple' object is not callable
>>>
>>> del tuple  # You can delete the object tuple created earlier to make it work
>>> tuple(l)
(4, 5, 6)

Here’s the problem… Since you have used a tuple variable to hold a tuple (45, 34) earlier… So, now tuple is an object of type tuple now…

It is no more a type and hence, it is no more Callable.

Never use any built-in types as your variable name… You do have any other name to use. Use any arbitrary name for your variable instead…


回答 3

tuple(l)自Python> =起,要向中添加其他替代方法,3.5您可以执行以下操作:

t = *l,  # or t = (*l,) 

简短一点快,但可能是从可读性受到影响。

这实际上将列表解压缩到l元组文字中,该元组文字是由于单个逗号的存在而创建的,


Ps:您收到的错误是由于名称的掩盖所致,tuple即您在某处(例如)分配了名称元组tuple = (1, 2, 3)

使用del tuple您应该很好。

To add another alternative to tuple(l), as of Python >= 3.5 you can do:

t = *l,  # or t = (*l,) 

short, a bit faster but probably suffers from readability.

This essentially unpacks the list l inside a tuple literal which is created due to the presence of the single comma ,.


P.s: The error you are receiving is due to masking of the name tuple i.e you assigned to the name tuple somewhere e.g tuple = (1, 2, 3).

Using del tuple you should be good to go.


回答 4

我找到了许多最新的答案,并且得到了正确答案,但会为答案添加一些新内容。

在Python有无限的方法可以做到这一点,这里有一些情况下,
正常的方式

>>> l= [1,2,"stackoverflow","python"]
>>> l
[1, 2, 'stackoverflow', 'python']
>>> tup = tuple(l)
>>> type(tup)
<type 'tuple'>
>>> tup
(1, 2, 'stackoverflow', 'python')

聪明的方法

>>>tuple(item for item in l)
(1, 2, 'stackoverflow', 'python')

请记住,元组是不变的,用于存储有价值的东西。例如,密码,密钥或哈希存储在元组或字典中。如果需要刀,为什么要用剑切苹果。明智地使用它,还可以使您的程序高效。

I find many answers up to date and properly answered but will add something new to stack of answers.

In python there are infinite ways to do this, here are some instances
Normal way

>>> l= [1,2,"stackoverflow","python"]
>>> l
[1, 2, 'stackoverflow', 'python']
>>> tup = tuple(l)
>>> type(tup)
<type 'tuple'>
>>> tup
(1, 2, 'stackoverflow', 'python')

smart way

>>>tuple(item for item in l)
(1, 2, 'stackoverflow', 'python')

Remember tuple is immutable ,used for storing something valuable. For example password,key or hashes are stored in tuples or dictionaries. If knife is needed why to use sword to cut apples. Use it wisely, it will also make your program efficient.


将元组扩展为参数

问题:将元组扩展为参数

有没有一种方法可以将Python元组扩展为函数-作为实际参数?

例如,这里expand()做了魔术:

some_tuple = (1, "foo", "bar")

def myfun(number, str1, str2):
    return (number * 2, str1 + str2, str2 + str1)

myfun(expand(some_tuple)) # (2, "foobar", "barfoo")

我知道可以将其定义myfunmyfun((a, b, c)),但是当然可能会有遗留代码。谢谢

Is there a way to expand a Python tuple into a function – as actual parameters?

For example, here expand() does the magic:

some_tuple = (1, "foo", "bar")

def myfun(number, str1, str2):
    return (number * 2, str1 + str2, str2 + str1)

myfun(expand(some_tuple)) # (2, "foobar", "barfoo")

I know one could define myfun as myfun((a, b, c)), but of course there may be legacy code. Thanks


回答 0

myfun(*some_tuple)完全符合您的要求。的*操作者只需解包元组(或任何可迭代),并把它们作为位置函数的自变量。阅读有关解压缩参数的更多信息。

myfun(*some_tuple) does exactly what you request. The * operator simply unpacks the tuple (or any iterable) and passes them as the positional arguments to the function. Read more about unpacking arguments.


回答 1

请注意,您还可以扩展参数列表的一部分:

myfun(1, *("foo", "bar"))

Note that you can also expand part of argument list:

myfun(1, *("foo", "bar"))

回答 2

看一下Python教程的第4.7.3和4.7.4节。它讨论将元组作为参数传递。

我还将考虑使用命名参数(并传递字典),而不是使用元组并传递序列。当位置不直观或有多个参数时,我发现使用位置参数是一种不好的做法。

Take a look at the Python tutorial section 4.7.3 and 4.7.4. It talks about passing tuples as arguments.

I would also consider using named parameters (and passing a dictionary) instead of using a tuple and passing a sequence. I find the use of positional arguments to be a bad practice when the positions are not intuitive or there are multiple parameters.


回答 3

这是功能编程方法。它从语法糖中提升了元组扩展功能:

apply_tuple = lambda f, t: f(*t)

用法示例:

from toolz import * 
from operator import add, eq

apply_tuple = curry(apply_tuple)

thread_last(
    [(1,2), (3,4)],
    (map, apply_tuple(add)),
    list,
    (eq, [3, 7])
)
# Prints 'True'

咖喱的redefiniton apply_tuple节省了大量的partial,从长远来看通话。

This is the functional programming method. It lifts the tuple expansion feature out of syntax sugar:

apply_tuple = lambda f, t: f(*t)

Example usage:

from toolz import * 
from operator import add, eq

apply_tuple = curry(apply_tuple)

thread_last(
    [(1,2), (3,4)],
    (map, apply_tuple(add)),
    list,
    (eq, [3, 7])
)
# Prints 'True'

curry redefiniton of apply_tuple saves a lot of partial calls in the long run.


Python中的“命名元组”是什么?

问题:Python中的“命名元组”是什么?

阅读Python 3.1中更改后,我发现了一些意外……

sys.version_info元组现在是一个命名的元组

我以前从未听说过命名元组,并且我认为元素可以用数字(如在元组和列表中)或键(如字典中)索引。我从未想到它们可以同时被索引。

因此,我的问题是:

  • 什么叫元组?
  • 如何使用它们?
  • 为什么/何时应该使用命名元组而不是普通元组?
  • 为什么/何时应该使用普通元组而不是命名元组?
  • 是否有某种“命名列表”(命名元组的可变版本)?

Reading the changes in Python 3.1, I found something… unexpected:

The sys.version_info tuple is now a named tuple:

I never heard about named tuples before, and I thought elements could either be indexed by numbers (like in tuples and lists) or by keys (like in dicts). I never expected they could be indexed both ways.

Thus, my questions are:

  • What are named tuples?
  • How to use them?
  • Why/when should I use named tuples instead of normal tuples?
  • Why/when should I use normal tuples instead of named tuples?
  • Is there any kind of “named list” (a mutable version of the named tuple)?

回答 0

命名元组基本上是易于创建的轻量级对象类型。可以使用类对象变量解引用或标准元组语法来引用已命名的元组实例。struct除了它们是不可变的,它们可以类似于或其他常见的记录类型使用。它们是在Python 2.6和Python 3.0中添加的,尽管在Python 2.4中实现秘诀

例如,通常将一个点表示为元组(x, y)。这导致如下代码:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)

使用命名元组,它变得更具可读性:

from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)

但是,命名元组仍然与普通元组向后兼容,因此以下内容仍然有效:

Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
 # use tuple unpacking
x1, y1 = pt1

因此,在您认为对象表示法将使您的代码更具pythonic性且更易于阅读的任何地方都应使用命名元组而不是元组。我个人已经开始使用它们来表示非常简单的值类型,尤其是在将它们作为参数传递给函数时。它使函数更具可读性,而看不到元组包装的上下文。

此外,您还可以替换没有功能的普通不可变,仅将它们替换为字段。您甚至可以将命名的元组类型用作基类:

class Point(namedtuple('Point', 'x y')):
    [...]

但是,与元组一样,命名元组中的属性是不可变的:

>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute

如果要能够更改值,则需要另一种类型。对于可变记录类型,有一个方便的用法,可让您为属性设置新值。

>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
    2.0

但是,我不知道有任何形式的“命名列表”可让您添加新字段。在这种情况下,您可能只想使用字典。命名的元组可以转换为字典,使用pt1._asdict()该返回{'x': 1.0, 'y': 5.0}可以使用所有常用的字典功能进行操作。

如前所述,您应该查看文档以获取构成这些示例的更多信息。

Named tuples are basically easy-to-create, lightweight object types. Named tuple instances can be referenced using object-like variable dereferencing or the standard tuple syntax. They can be used similarly to struct or other common record types, except that they are immutable. They were added in Python 2.6 and Python 3.0, although there is a recipe for implementation in Python 2.4.

For example, it is common to represent a point as a tuple (x, y). This leads to code like the following:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)

Using a named tuple it becomes more readable:

from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)

However, named tuples are still backwards compatible with normal tuples, so the following will still work:

Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
 # use tuple unpacking
x1, y1 = pt1

Thus, you should use named tuples instead of tuples anywhere you think object notation will make your code more pythonic and more easily readable. I personally have started using them to represent very simple value types, particularly when passing them as parameters to functions. It makes the functions more readable, without seeing the context of the tuple packing.

Furthermore, you can also replace ordinary immutable classes that have no functions, only fields with them. You can even use your named tuple types as base classes:

class Point(namedtuple('Point', 'x y')):
    [...]

However, as with tuples, attributes in named tuples are immutable:

>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute

If you want to be able change the values, you need another type. There is a handy recipe for mutable recordtypes which allow you to set new values to attributes.

>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
    2.0

I am not aware of any form of “named list” that lets you add new fields, however. You may just want to use a dictionary in this situation. Named tuples can be converted to dictionaries using pt1._asdict() which returns {'x': 1.0, 'y': 5.0} and can be operated upon with all the usual dictionary functions.

As already noted, you should check the documentation for more information from which these examples were constructed.


回答 1

namedtuple是用于创建元组类的工厂函数。通过该类,我们可以创建可通过名称调用的元组。

import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False)   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1

row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values

print row   #Prints: Row(a=2, b=3, c=4)

namedtuple is a factory function for making a tuple class. With that class we can create tuples that are callable by name also.

import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False)   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1

row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values

print row   #Prints: Row(a=2, b=3, c=4)

回答 2

什么叫元组?

一个命名的元组是一个元组。

它完成了元组可以做的所有事情。

但这不仅仅是一个元组。

它是元组的特定子类,它是根据您的规范以编程方式创建的,具有命名字段和固定长度。

例如,这创建了一个元组的子类,除了具有固定的长度(在这种情况下为三个)之外,它还可以在使用元组的任何地方使用而不会中断。这称为Liskov替代性。

Python 3.6中的新功能,我们可以使用类定义typing.NamedTuple来创建namedtuple:

from typing import NamedTuple

class ANamedTuple(NamedTuple):
    """a docstring"""
    foo: int
    bar: str
    baz: list

上面与下面相同,除了上面还带有类型注释和文档字符串。以下在Python 2+中可用:

>>> from collections import namedtuple
>>> class_name = 'ANamedTuple'
>>> fields = 'foo bar baz'
>>> ANamedTuple = namedtuple(class_name, fields)

实例化它:

>>> ant = ANamedTuple(1, 'bar', [])

我们可以检查它并使用其属性:

>>> ant
ANamedTuple(foo=1, bar='bar', baz=[])
>>> ant.foo
1
>>> ant.bar
'bar'
>>> ant.baz.append('anything')
>>> ant.baz
['anything']

更深入的解释

要了解命名元组,您首先需要知道什么是元组。元组本质上是一个不变的(不能在内存中就地更改)列表。

这是使用常规元组的方法:

>>> student_tuple = 'Lisa', 'Simpson', 'A'
>>> student_tuple
('Lisa', 'Simpson', 'A')
>>> student_tuple[0]
'Lisa'
>>> student_tuple[1]
'Simpson'
>>> student_tuple[2]
'A'

您可以使用可迭代的拆包扩展元组:

>>> first, last, grade = student_tuple
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'

命名元组是允许通过名称而不是索引访问其元素的元组!

您可以这样创建一个namedtuple:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', ['first', 'last', 'grade'])

您还可以使用名称以空格分隔的单个字符串,该API的可读性更高:

>>> Student = namedtuple('Student', 'first last grade')

如何使用它们?

您可以做元组可以做的所有事情(见上文),还可以执行以下操作:

>>> named_student_tuple = Student('Lisa', 'Simpson', 'A')
>>> named_student_tuple.first
'Lisa'
>>> named_student_tuple.last
'Simpson'
>>> named_student_tuple.grade
'A'
>>> named_student_tuple._asdict()
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> vars(named_student_tuple)
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> new_named_student_tuple = named_student_tuple._replace(first='Bart', grade='C')
>>> new_named_student_tuple
Student(first='Bart', last='Simpson', grade='C')

有评论者问:

在大型脚本或程序中,通常在哪里定义命名元组?

您创建的类型namedtuple基本上是可以用简单的速记创建的类。像上课一样对待他们。在模块级别上定义它们,以便pickle和其他用户可以找到它们。

在全局模块级别上的工作示例:

>>> from collections import namedtuple
>>> NT = namedtuple('NT', 'foo bar')
>>> nt = NT('foo', 'bar')
>>> import pickle
>>> pickle.loads(pickle.dumps(nt))
NT(foo='foo', bar='bar')

这证明了查找定义的失败:

>>> def foo():
...     LocalNT = namedtuple('LocalNT', 'foo bar')
...     return LocalNT('foo', 'bar')
... 
>>> pickle.loads(pickle.dumps(foo()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class '__main__.LocalNT'>: attribute lookup LocalNT on __main__ failed

为什么/何时应该使用命名元组而不是普通元组?

在改进代码以使元组元素的语义在代码中表达时使用它们。

如果不使用数据属性不变且没有功能的对象,则可以使用它们代替对象。

您也可以将它们子类化以添加功能,例如

class Point(namedtuple('Point', 'x y')):
    """adding functionality to a named tuple"""
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

为什么/何时应该使用普通元组而不是命名元组?

从使用命名元组切换到元组可能是一种回归。前期设计决策集中在使用元组时,是否值得使用额外代码带来的成本来提高可读性。

元组和元组之间没有使用额外的内存。

是否有某种“命名列表”(命名元组的可变版本)?

您正在寻找实现静态大小列表的所有功能的带槽对象,或者寻找像命名元组一样工作的子类列表(并以某种方式阻止列表大小的改变)。

现在是第一个的扩展示例,甚至可以用Liskov替代:

from collections import Sequence

class MutableTuple(Sequence): 
    """Abstract Base Class for objects that work like mutable
    namedtuples. Subclass and define your named fields with 
    __slots__ and away you go.
    """
    __slots__ = ()
    def __init__(self, *args):
        for slot, arg in zip(self.__slots__, args):
            setattr(self, slot, arg)
    def __repr__(self):
        return type(self).__name__ + repr(tuple(self))
    # more direct __iter__ than Sequence's
    def __iter__(self): 
        for name in self.__slots__:
            yield getattr(self, name)
    # Sequence requires __getitem__ & __len__:
    def __getitem__(self, index):
        return getattr(self, self.__slots__[index])
    def __len__(self):
        return len(self.__slots__)

要使用,只需继承并定义__slots__

class Student(MutableTuple):
    __slots__ = 'first', 'last', 'grade' # customize 


>>> student = Student('Lisa', 'Simpson', 'A')
>>> student
Student('Lisa', 'Simpson', 'A')
>>> first, last, grade = student
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'
>>> student[0]
'Lisa'
>>> student[2]
'A'
>>> len(student)
3
>>> 'Lisa' in student
True
>>> 'Bart' in student
False
>>> student.first = 'Bart'
>>> for i in student: print(i)
... 
Bart
Simpson
A

What are named tuples?

A named tuple is a tuple.

It does everything a tuple can.

But it’s more than just a tuple.

It’s a specific subclass of a tuple that is programmatically created to your specification, with named fields and a fixed length.

This, for example, creates a subclass of tuple, and aside from being of fixed length (in this case, three), it can be used everywhere a tuple is used without breaking. This is known as Liskov substitutability.

New in Python 3.6, we can use a class definition with typing.NamedTuple to create a namedtuple:

from typing import NamedTuple

class ANamedTuple(NamedTuple):
    """a docstring"""
    foo: int
    bar: str
    baz: list

The above is the same as the below, except the above additionally has type annotations and a docstring. The below is available in Python 2+:

>>> from collections import namedtuple
>>> class_name = 'ANamedTuple'
>>> fields = 'foo bar baz'
>>> ANamedTuple = namedtuple(class_name, fields)

This instantiates it:

>>> ant = ANamedTuple(1, 'bar', [])

We can inspect it and use its attributes:

>>> ant
ANamedTuple(foo=1, bar='bar', baz=[])
>>> ant.foo
1
>>> ant.bar
'bar'
>>> ant.baz.append('anything')
>>> ant.baz
['anything']

Deeper explanation

To understand named tuples, you first need to know what a tuple is. A tuple is essentially an immutable (can’t be changed in-place in memory) list.

Here’s how you might use a regular tuple:

>>> student_tuple = 'Lisa', 'Simpson', 'A'
>>> student_tuple
('Lisa', 'Simpson', 'A')
>>> student_tuple[0]
'Lisa'
>>> student_tuple[1]
'Simpson'
>>> student_tuple[2]
'A'

You can expand a tuple with iterable unpacking:

>>> first, last, grade = student_tuple
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'

Named tuples are tuples that allow their elements to be accessed by name instead of just index!

You make a namedtuple like this:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', ['first', 'last', 'grade'])

You can also use a single string with the names separated by spaces, a slightly more readable use of the API:

>>> Student = namedtuple('Student', 'first last grade')

How to use them?

You can do everything tuples can do (see above) as well as do the following:

>>> named_student_tuple = Student('Lisa', 'Simpson', 'A')
>>> named_student_tuple.first
'Lisa'
>>> named_student_tuple.last
'Simpson'
>>> named_student_tuple.grade
'A'
>>> named_student_tuple._asdict()
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> vars(named_student_tuple)
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> new_named_student_tuple = named_student_tuple._replace(first='Bart', grade='C')
>>> new_named_student_tuple
Student(first='Bart', last='Simpson', grade='C')

A commenter asked:

In a large script or programme, where does one usually define a named tuple?

The types you create with namedtuple are basically classes you can create with easy shorthand. Treat them like classes. Define them on the module level, so that pickle and other users can find them.

The working example, on the global module level:

>>> from collections import namedtuple
>>> NT = namedtuple('NT', 'foo bar')
>>> nt = NT('foo', 'bar')
>>> import pickle
>>> pickle.loads(pickle.dumps(nt))
NT(foo='foo', bar='bar')

And this demonstrates the failure to lookup the definition:

>>> def foo():
...     LocalNT = namedtuple('LocalNT', 'foo bar')
...     return LocalNT('foo', 'bar')
... 
>>> pickle.loads(pickle.dumps(foo()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class '__main__.LocalNT'>: attribute lookup LocalNT on __main__ failed

Why/when should I use named tuples instead of normal tuples?

Use them when it improves your code to have the semantics of tuple elements expressed in your code.

You can use them instead of an object if you would otherwise use an object with unchanging data attributes and no functionality.

You can also subclass them to add functionality, for example:

class Point(namedtuple('Point', 'x y')):
    """adding functionality to a named tuple"""
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

Why/when should I use normal tuples instead of named tuples?

It would probably be a regression to switch from using named tuples to tuples. The upfront design decision centers around whether the cost from the extra code involved is worth the improved readability when the tuple is used.

There is no extra memory used by named tuples versus tuples.

Is there any kind of “named list” (a mutable version of the named tuple)?

You’re looking for either a slotted object that implements all of the functionality of a statically sized list or a subclassed list that works like a named tuple (and that somehow blocks the list from changing in size.)

A now expanded, and perhaps even Liskov substitutable, example of the first:

from collections import Sequence

class MutableTuple(Sequence): 
    """Abstract Base Class for objects that work like mutable
    namedtuples. Subclass and define your named fields with 
    __slots__ and away you go.
    """
    __slots__ = ()
    def __init__(self, *args):
        for slot, arg in zip(self.__slots__, args):
            setattr(self, slot, arg)
    def __repr__(self):
        return type(self).__name__ + repr(tuple(self))
    # more direct __iter__ than Sequence's
    def __iter__(self): 
        for name in self.__slots__:
            yield getattr(self, name)
    # Sequence requires __getitem__ & __len__:
    def __getitem__(self, index):
        return getattr(self, self.__slots__[index])
    def __len__(self):
        return len(self.__slots__)

And to use, just subclass and define __slots__:

class Student(MutableTuple):
    __slots__ = 'first', 'last', 'grade' # customize 


>>> student = Student('Lisa', 'Simpson', 'A')
>>> student
Student('Lisa', 'Simpson', 'A')
>>> first, last, grade = student
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'
>>> student[0]
'Lisa'
>>> student[2]
'A'
>>> len(student)
3
>>> 'Lisa' in student
True
>>> 'Bart' in student
False
>>> student.first = 'Bart'
>>> for i in student: print(i)
... 
Bart
Simpson
A

回答 3

namedtuple是一个很棒的功能,它们是数据的完美容器。当您必须“存储”数据时,可以使用元组或字典,例如:

user = dict(name="John", age=20)

要么:

user = ("John", 20)

字典方法是压倒性的,因为字典比元组易变且速度慢。另一方面,元组是不可变的且轻量级的,但是对于数据字段中的大量条目却缺乏可读性。

namedtuple是这两种方法的完美折衷,它们具有出色的可读性,轻巧性和不变性(而且它们是多态的!)。

namedtuples are a great feature, they are perfect container for data. When you have to “store” data you would use tuples or dictionaries, like:

user = dict(name="John", age=20)

or:

user = ("John", 20)

The dictionary approach is overwhelming, since dict are mutable and slower than tuples. On the other hand, the tuples are immutable and lightweight but lack readability for a great number of entries in the data fields.

namedtuples are the perfect compromise for the two approaches, the have great readability, lightweightness and immutability (plus they are polymorphic!).


回答 4

命名元组允许向后兼容与检查像这样的版本的代码

>>> sys.version_info[0:2]
(3, 1)

同时通过使用此语法使将来的代码更加明确

>>> sys.version_info.major
3
>>> sys.version_info.minor
1

named tuples allow backward compatibility with code that checks for the version like this

>>> sys.version_info[0:2]
(3, 1)

while allowing future code to be more explicit by using this syntax

>>> sys.version_info.major
3
>>> sys.version_info.minor
1

回答 5

元组

是清理代码并使代码更具可读性的最简单方法之一。它自我记录元组中发生的事情。Namedtuple实例不具有按实例字典,因此它们与常规元组的存储效率相同,这使它们比字典快。

from collections import namedtuple

Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])

 p = Color(170, 0.1, 0.6)
 if p.saturation >= 0.5:
     print "Whew, that is bright!"
 if p.luminosity >= 0.5:
     print "Wow, that is light"

如果不命名元组中的每个元素,它将显示为:

p = (170, 0.1, 0.6)
if p[1] >= 0.5:
    print "Whew, that is bright!"
if p[2]>= 0.5:
   print "Wow, that is light"

要理解第一个示例中发生的事情要困难得多。对于namedtuple,每个字段都有一个名称。您可以通过名称而不是位置或索引来访问它。代替p[1],我们可以称它为p.saturation。更容易理解。而且看起来更干净。

创建namedtuple的实例比创建字典要容易。

# dictionary
>>>p = dict(hue = 170, saturation = 0.1, luminosity = 0.6)
>>>p['hue']
170

#nametuple
>>>from collections import namedtuple
>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)
>>>p.hue
170

什么时候可以使用namedtuple

  1. 如前所述,namedtuple使理解元组更加容易。因此,如果您需要引用元组中的项目,那么将它们创建为namedtuples就很有意义。
  2. 除了比字典轻巧之外,namedtuple还保留了与字典不同的顺序。
  3. 如上例所示,创建namedtuple的实例比使用字典更简单。并且在命名元组中引用该项目看起来比字典更干净。p.hue而不是 p['hue']

语法

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • namedtuple在集合库中。
  • typename:这是新的元组子类的名称。
  • field_names:每个字段的名称序列。它可以是列表['x', 'y', 'z']或字符串中的序列x y z(不带逗号,只有空格)或x, y, z
  • 重命名:如果重命名为True,则无效的字段名称将自动替换为位置名称。例如,['abc', 'def', 'ghi','abc']将转换为['abc', '_1', 'ghi', '_3'],消除关键字'def'(因为它是定义函数的保留字)和重复的fieldname 'abc'
  • verbose:如果verbose为True,则在构建之前就打印类定义。

如果选择,您仍然可以按名称元组的位置访问它们。p[1] == p.saturation。它仍然像普通的元组一样打开包装。

方法

支持所有常规元组方法。例如:min(),max(),len(),并入(+),索引,切片等,而不是在其中。namedtuple还有一些其他附加名称。注意:所有这些都以下划线开头。_replace_make_asdict

_replace 返回命名元组的新实例,用新值替换指定字段。

语法

somenamedtuple._replace(kwargs)

>>>from collections import namedtuple

>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)

>>>p._replace(hue=87)
Color(87, 0.1, 0.6)

>>>p._replace(hue=87, saturation=0.2)
Color(87, 0.2, 0.6)

注意:字段名称不带引号;他们是这里的关键词。 请记住:元组是不可变的-即使它们是namedtuple并具有_replace方法。的_replace产生new的实例; 它不会修改原始值或替换旧值。您当然可以将新结果保存到变量中。p = p._replace(hue=169)

_make

根据现有序列创建新实例或使其可迭代。

语法

somenamedtuple._make(iterable)

 >>>data = (170, 0.1, 0.6)
 >>>Color._make(data)
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make([170, 0.1, 0.6])  #the list is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make((170, 0.1, 0.6))  #the tuple is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make(170, 0.1, 0.6) 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<string>", line 15, in _make
TypeError: 'float' object is not callable

最后一个发生了什么?括号内的项目应该是可迭代的。因此,括号内的列表或元组可以工作,但是未封装为可迭代值的值序列将返回错误。

_asdict

返回一个新的OrderedDict,它将字段名称映射到其对应的值。

语法

somenamedtuple._asdict()

 >>>p._asdict()
OrderedDict([('hue', 169), ('saturation', 0.1), ('luminosity', 0.6)])

参考https : //www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

还有一个命名列表,类似于命名元组,但是可变 https://pypi.python.org/pypi/namedlist

namedtuple

is one of the easiest ways to clean up your code and make it more readable. It self-documents what is happening in the tuple. Namedtuples instances are just as memory efficient as regular tuples as they do not have per-instance dictionaries, making them faster than dictionaries.

from collections import namedtuple

Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])

 p = Color(170, 0.1, 0.6)
 if p.saturation >= 0.5:
     print "Whew, that is bright!"
 if p.luminosity >= 0.5:
     print "Wow, that is light"

Without naming each element in the tuple, it would read like this:

p = (170, 0.1, 0.6)
if p[1] >= 0.5:
    print "Whew, that is bright!"
if p[2]>= 0.5:
   print "Wow, that is light"

It is so much harder to understand what is going on in the first example. With a namedtuple, each field has a name. And you access it by name rather than position or index. Instead of p[1], we can call it p.saturation. It’s easier to understand. And it looks cleaner.

Creating an instance of the namedtuple is easier than creating a dictionary.

# dictionary
>>>p = dict(hue = 170, saturation = 0.1, luminosity = 0.6)
>>>p['hue']
170

#nametuple
>>>from collections import namedtuple
>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)
>>>p.hue
170

When might you use namedtuple

  1. As just stated, the namedtuple makes understanding tuples much easier. So if you need to reference the items in the tuple, then creating them as namedtuples just makes sense.
  2. Besides being more lightweight than a dictionary, namedtuple also keeps the order unlike the dictionary.
  3. As in the example above, it is simpler to create an instance of namedtuple than dictionary. And referencing the item in the named tuple looks cleaner than a dictionary. p.hue rather than p['hue'].

The syntax

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • namedtuple is in the collections library.
  • typename: This is the name of the new tuple subclass.
  • field_names: A sequence of names for each field. It can be a sequence as in a list ['x', 'y', 'z'] or string x y z (without commas, just whitespace) or x, y, z.
  • rename: If rename is True, invalid fieldnames are automatically replaced with positional names. For example, ['abc', 'def', 'ghi','abc'] is converted to ['abc', '_1', 'ghi', '_3'], eliminating the keyword 'def' (since that is a reserved word for defining functions) and the duplicate fieldname 'abc'.
  • verbose: If verbose is True, the class definition is printed just before being built.

You can still access namedtuples by their position, if you so choose. p[1] == p.saturation. It still unpacks like a regular tuple.

Methods

All the regular tuple methods are supported. Ex: min(), max(), len(), in, not in, concatenation (+), index, slice, etc. And there are a few additional ones for namedtuple. Note: these all start with an underscore. _replace, _make, _asdict.

_replace Returns a new instance of the named tuple replacing specified fields with new values.

The syntax

somenamedtuple._replace(kwargs)

Example

>>>from collections import namedtuple

>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)

>>>p._replace(hue=87)
Color(87, 0.1, 0.6)

>>>p._replace(hue=87, saturation=0.2)
Color(87, 0.2, 0.6)

Notice: The field names are not in quotes; they are keywords here. Remember: Tuples are immutable – even if they are namedtuples and have the _replace method. The _replace produces a new instance; it does not modify the original or replace the old value. You can of course save the new result to the variable. p = p._replace(hue=169)

_make

Makes a new instance from an existing sequence or iterable.

The syntax

somenamedtuple._make(iterable)

Example

 >>>data = (170, 0.1, 0.6)
 >>>Color._make(data)
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make([170, 0.1, 0.6])  #the list is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make((170, 0.1, 0.6))  #the tuple is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make(170, 0.1, 0.6) 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<string>", line 15, in _make
TypeError: 'float' object is not callable

What happened with the last one? The item inside the parenthesis should be the iterable. So a list or tuple inside the parenthesis works, but the sequence of values without enclosing as an iterable returns an error.

_asdict

Returns a new OrderedDict which maps field names to their corresponding values.

The syntax

somenamedtuple._asdict()

Example

 >>>p._asdict()
OrderedDict([('hue', 169), ('saturation', 0.1), ('luminosity', 0.6)])

Reference: https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

There is also named list which is similar to named tuple but mutable https://pypi.python.org/pypi/namedlist


回答 6

什么是namedtuple?

顾名思义,namedtuple是具有名称的元组。在标准元组中,我们使用索引访问元素,而namedtuple允许用户定义元素的名称。这非常方便,尤其是处理csv(逗号分隔值)文件并处理复杂而又庞大的数据集时,其中的代码因使用索引而变得混乱(不是pythonic)。

如何使用它们?

>>>from collections import namedtuple
>>>saleRecord = namedtuple('saleRecord','shopId saleDate salesAmout totalCustomers')
>>>
>>>
>>>#Assign values to a named tuple 
>>>shop11=saleRecord(11,'2015-01-01',2300,150) 
>>>shop12=saleRecord(shopId=22,saleDate="2015-01-01",saleAmout=1512,totalCustomers=125)

阅读

>>>#Reading as a namedtuple
>>>print("Shop Id =",shop12.shopId)
12
>>>print("Sale Date=",shop12.saleDate)
2015-01-01
>>>print("Sales Amount =",shop12.salesAmount)
1512
>>>print("Total Customers =",shop12.totalCustomers)
125

CSV处理中有趣的场景:

from csv import reader
from collections import namedtuple

saleRecord = namedtuple('saleRecord','shopId saleDate totalSales totalCustomers')
fileHandle = open("salesRecord.csv","r")
csvFieldsList=csv.reader(fileHandle)
for fieldsList in csvFieldsList:
    shopRec = saleRecord._make(fieldsList)
    overAllSales += shopRec.totalSales;

print("Total Sales of The Retail Chain =",overAllSales)

What is namedtuple ?

As the name suggests, namedtuple is a tuple with name. In standard tuple, we access the elements using the index, whereas namedtuple allows user to define name for elements. This is very handy especially processing csv (comma separated value) files and working with complex and large dataset, where the code becomes messy with the use of indices (not so pythonic).

How to use them ?

>>>from collections import namedtuple
>>>saleRecord = namedtuple('saleRecord','shopId saleDate salesAmout totalCustomers')
>>>
>>>
>>>#Assign values to a named tuple 
>>>shop11=saleRecord(11,'2015-01-01',2300,150) 
>>>shop12=saleRecord(shopId=22,saleDate="2015-01-01",saleAmout=1512,totalCustomers=125)

Reading

>>>#Reading as a namedtuple
>>>print("Shop Id =",shop12.shopId)
12
>>>print("Sale Date=",shop12.saleDate)
2015-01-01
>>>print("Sales Amount =",shop12.salesAmount)
1512
>>>print("Total Customers =",shop12.totalCustomers)
125

Interesting Scenario in CSV Processing :

from csv import reader
from collections import namedtuple

saleRecord = namedtuple('saleRecord','shopId saleDate totalSales totalCustomers')
fileHandle = open("salesRecord.csv","r")
csvFieldsList=csv.reader(fileHandle)
for fieldsList in csvFieldsList:
    shopRec = saleRecord._make(fieldsList)
    overAllSales += shopRec.totalSales;

print("Total Sales of The Retail Chain =",overAllSales)

回答 7

在Python内部,有一个很好使用的容器,称为命名元组,它可以用于创建类的定义,并具有原始元组的所有功能。

使用命名元组将直接应用于默认的类模板以生成一个简单的类,此方法允许使用大量代码来提高可读性,并且在定义类时也非常方便。

In Python inside there is a good use of container called a named tuple, it can be used to create a definition of class and has all the features of the original tuple.

Using named tuple will be directly applied to the default class template to generate a simple class, this method allows a lot of code to improve readability and it is also very convenient when defining a class.


回答 8

使用命名元组的另一种方法(新方法)是通过键入包来使用NamedTuple: namedtuple中键入提示

让我们以本文中最常见的答案为例,看看如何使用它。

(1)在使用命名元组之前,代码是这样的:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
print(line_length)

(2)现在我们使用命名的元组

from typing import NamedTuple, Number

继承NamedTuple类,并在新类中定义变量名称。测试是类的名称。

class test(NamedTuple):
x: Number
y: Number

从类创建实例并为其分配值

pt1 = test(1.0, 5.0)   # x is 1.0, and y is 5.0. The order matters
pt2 = test(2.5, 1.5)

使用实例中的变量进行计算

line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
print(line_length)

Another way (a new way) to use named tuple is using NamedTuple from typing package: Type hints in namedtuple

Let’s use the example of the top answer in this post to see how to use it.

(1) Before using the named tuple, the code is like this:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
print(line_length)

(2) Now we use the named tuple

from typing import NamedTuple, Number

inherit the NamedTuple class and define the variable name in the new class. test is the name of the class.

class test(NamedTuple):
x: Number
y: Number

create instances from the class and assign values to them

pt1 = test(1.0, 5.0)   # x is 1.0, and y is 5.0. The order matters
pt2 = test(2.5, 1.5)

use the variables from the instances to calculate

line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
print(line_length)

回答 9

尝试这个:

collections.namedtuple()

基本上,namedtuples易于创建的轻量级对象类型。他们将元组变成方便执行简单任务的容器。用namedtuples,您不必使用整数索引来访问元组的成员。

例子:

代码1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

代码2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

Try this:

collections.namedtuple()

Basically, namedtuples are easy to create, lightweight object types. They turn tuples into convenient containers for simple tasks. With namedtuples, you don’t have to use integer indices for accessing members of a tuple.

Examples:

Code 1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

Code 2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

回答 10

其他人都已经回答了,但是我想我还有其他事情要补充。

Namedtuple可以直观地视为定义类的捷径。

请参阅定义一个繁琐而常规的方法class

class Duck:
    def __init__(self, color, weight):
        self.color = color
        self.weight = weight
red_duck = Duck('red', '10')

    In [50]: red_duck
    Out[50]: <__main__.Duck at 0x1068e4e10>
    In [51]: red_duck.color
    Out[51]: 'red'

至于 namedtuple

from collections import namedtuple
Duck = namedtuple('Duck', ['color', 'weight'])
red_duck = Duck('red', '10')

In [54]: red_duck
Out[54]: Duck(color='red', weight='10')
In [55]: red_duck.color
Out[55]: 'red'

Everyone else has already answered it, but I think I still have something else to add.

Namedtuple could be intuitively deemed as a shortcut to define a class.

See a cumbersome and conventional way to define a class .

class Duck:
    def __init__(self, color, weight):
        self.color = color
        self.weight = weight
red_duck = Duck('red', '10')

    In [50]: red_duck
    Out[50]: <__main__.Duck at 0x1068e4e10>
    In [51]: red_duck.color
    Out[51]: 'red'

As for namedtuple

from collections import namedtuple
Duck = namedtuple('Duck', ['color', 'weight'])
red_duck = Duck('red', '10')

In [54]: red_duck
Out[54]: Duck(color='red', weight='10')
In [55]: red_duck.color
Out[55]: 'red'

如何按给定索引处的元素对列表/元组的列表/元组进行排序?

问题:如何按给定索引处的元素对列表/元组的列表/元组进行排序?

我在列表列表或元组列表中都有一些数据,如下所示:

data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]

我想按子集中的第二个元素排序。这意味着,由2,5,8,其中排序2(1,2,3)5是从(4,5,6)。常见的做法是什么?我应该将元组或列表存储在列表中吗?

I have some data either in a list of lists or a list of tuples, like this:

data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]

And I want to sort by the 2nd element in the subset. Meaning, sorting by 2,5,8 where 2 is from (1,2,3), 5 is from (4,5,6). What is the common way to do this? Should I store tuples or lists in my list?


回答 0

sorted_by_second = sorted(data, key=lambda tup: tup[1])

要么:

data.sort(key=lambda tup: tup[1])  # sorts in place
sorted_by_second = sorted(data, key=lambda tup: tup[1])

or:

data.sort(key=lambda tup: tup[1])  # sorts in place

回答 1

from operator import itemgetter
data.sort(key=itemgetter(1))
from operator import itemgetter
data.sort(key=itemgetter(1))

回答 2

如果您想将数组从高到低排序,我只想添加到Stephen的答案中,除了上面的注释中的另一种方法就是将其添加到行中:

reverse = True

结果将如下所示:

data.sort(key=lambda tup: tup[1], reverse=True)

I just want to add to Stephen’s answer if you want to sort the array from high to low, another way other than in the comments above is just to add this to the line:

reverse = True

and the result will be as follows:

data.sort(key=lambda tup: tup[1], reverse=True)

回答 3

为了按照多个条件进行排序,例如按元组中的第二个和第三个元素进行排序,

data = [(1,2,3),(1,2,1),(1,1,4)]

并定义一个lambda来返回描述优先级的元组,例如

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

For sorting by multiple criteria, namely for instance by the second and third elements in a tuple, let

data = [(1,2,3),(1,2,1),(1,1,4)]

and so define a lambda that returns a tuple that describes priority, for instance

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

回答 4

斯蒂芬的答案就是我会用的答案。为了完整起见,这是带有列表推导的DSU(装饰-排序-取消装饰)模式:

decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]

或者,更简洁地说:

[b for a,b in sorted((tup[1], tup) for tup in data)]

Python Sorting HowTo中所述,自Python 2.4启用关键功能以来,就没有必要这样做

Stephen’s answer is the one I’d use. For completeness, here’s the DSU (decorate-sort-undecorate) pattern with list comprehensions:

decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]

Or, more tersely:

[b for a,b in sorted((tup[1], tup) for tup in data)]

As noted in the Python Sorting HowTo, this has been unnecessary since Python 2.4, when key functions became available.


回答 5

为了对元组列表进行排序(<word>, <count>),以count降序和word字母顺序:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

我使用这种方法:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

它给了我结果:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

In order to sort a list of tuples (<word>, <count>), for count in descending order and word in alphabetical order:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

I use this method:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

and it gives me the result:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

回答 6

没有lambda:

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

Without lambda:

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

回答 7

itemgetter() 比…快一点 lambda tup: tup[1],但增长幅度相对较小(大约10%到25%)。

(IPython会话)

>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [tuple(values[i,:]) for i in range(len(values))]

>>> tpls[:5]    # display sample from list
[(1, 0, 0), 
 (8, 5, 5), 
 (5, 4, 0), 
 (5, 7, 7), 
 (4, 2, 1)]

>>> sorted(tpls[:5], key=itemgetter(1))    # example sort
[(1, 0, 0), 
 (4, 2, 1), 
 (5, 4, 0), 
 (8, 5, 5), 
 (5, 7, 7)]

>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop

>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop

itemgetter() is somewhat faster than lambda tup: tup[1], but the increase is relatively modest (around 10 to 25 percent).

(IPython session)

>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [tuple(values[i,:]) for i in range(len(values))]

>>> tpls[:5]    # display sample from list
[(1, 0, 0), 
 (8, 5, 5), 
 (5, 4, 0), 
 (5, 7, 7), 
 (4, 2, 1)]

>>> sorted(tpls[:5], key=itemgetter(1))    # example sort
[(1, 0, 0), 
 (4, 2, 1), 
 (5, 4, 0), 
 (8, 5, 5), 
 (5, 7, 7)]

>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop

>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop

回答 8

@Stephen的答案很关键!这是一个更好的可视化示例,

为Ready Player One粉丝大喊大叫!=)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

key是一个函数,将调用该函数来转换集合的项目以进行比较compareTo

传递给key的参数必须是可调用的。在这里,使用lambdacreate创建一个匿名函数(可调用)。
lambda的语法是单词lambda,后跟一个可迭代的名称,然后是单个代码块。

在下面的示例中,我们正在对元组列表进行排序,该元组列表包含某些事件和演员名称的信息记录时间。

我们按照事件发生的时间对该列表进行排序-这是元组的第0个元素。

注意- s.sort([cmp[, key[, reverse]]]) 将s的项目排序到位

@Stephen ‘s answer is to the point! Here is an example for better visualization,

Shout out for the Ready Player One fans! =)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

key is a function that will be called to transform the collection’s items for comparison.. like compareTo method in Java.

The parameter passed to key must be something that is callable. Here, the use of lambda creates an anonymous function (which is a callable).
The syntax of lambda is the word lambda followed by a iterable name then a single block of code.

Below example, we are sorting a list of tuple that holds the info abt time of certain event and actor name.

We are sorting this list by time of event occurrence – which is the 0th element of a tuple.

Note – s.sort([cmp[, key[, reverse]]]) sorts the items of s in place


回答 9

对元组进行排序非常简单:

tuple(sorted(t))

Sorting a tuple is quite simple:

tuple(sorted(t))

列表和元组之间有什么区别?

问题:列表和元组之间有什么区别?

有什么不同?

元组/列表的优点/缺点是什么?

What’s the difference?

What are the advantages / disadvantages of tuples / lists?


回答 0

除了元组是不可变的之外,还有语义上的区别应指导它们的使用。元组是异构数据结构(即,它们的条目具有不同的含义),而列表是同类序列。元组具有结构,列表具有顺序。

使用这种区别可以使代码更加明确和易于理解。

一个示例是成对的页和行号,以成对参考书中的位置,例如:

my_location = (42, 11)  # page number, line number

然后,您可以将其用作字典中的键来存储有关位置的注释。另一方面,列表可用于存储多个位置。自然地,人们可能想在列表中添加或删除位置,因此列表是可变的很有意义。另一方面,从现有位置添加或删除项目没有意义-因此,元组是不可变的。

在某些情况下,您可能想更改现有位置元组中的项目,例如在页面的各行中进行迭代时。但是元组不变性迫使您为每个新值创建一个新的位置元组。从表面上看,这似乎很不方便,但是使用这样的不可变数据是值类型和函数编程技术的基石,可以具有很多优点。

关于此问题,有一些有趣的文章,例如“ Python元组不仅仅是常量列表”“了解Python中的元组与列表”。官方Python文档也提到了这一点

“组是不可变的,并且通常包含一个异类序列…”。

在像Haskell这样的静态类型语言中,元组中的值通常具有不同的类型,并且元组的长度必须固定。在列表中,所有值都具有相同的类型,并且长度不是固定的。因此区别非常明显。

最后,在Python中有一个namedtuple,这很有意义,因为一个元组已经被认为具有结构。这强调了元组是类和实例的轻量级替代方案的思想。

Apart from tuples being immutable there is also a semantic distinction that should guide their usage. Tuples are heterogeneous data structures (i.e., their entries have different meanings), while lists are homogeneous sequences. Tuples have structure, lists have order.

Using this distinction makes code more explicit and understandable.

One example would be pairs of page and line number to reference locations in a book, e.g.:

my_location = (42, 11)  # page number, line number

You can then use this as a key in a dictionary to store notes on locations. A list on the other hand could be used to store multiple locations. Naturally one might want to add or remove locations from the list, so it makes sense that lists are mutable. On the other hand it doesn’t make sense to add or remove items from an existing location – hence tuples are immutable.

There might be situations where you want to change items within an existing location tuple, for example when iterating through the lines of a page. But tuple immutability forces you to create a new location tuple for each new value. This seems inconvenient on the face of it, but using immutable data like this is a cornerstone of value types and functional programming techniques, which can have substantial advantages.

There are some interesting articles on this issue, e.g. “Python Tuples are Not Just Constant Lists” or “Understanding tuples vs. lists in Python”. The official Python documentation also mentions this

“Tuples are immutable, and usually contain an heterogeneous sequence …”.

In a statically typed language like Haskell the values in a tuple generally have different types and the length of the tuple must be fixed. In a list the values all have the same type and the length is not fixed. So the difference is very obvious.

Finally there is the namedtuple in Python, which makes sense because a tuple is already supposed to have structure. This underlines the idea that tuples are a light-weight alternative to classes and instances.


回答 1

列表和元组之间的区别

  1. 文字

    someTuple = (1,2)
    someList  = [1,2] 
  2. 尺寸

    a = tuple(range(1000))
    b = list(range(1000))
    
    a.__sizeof__() # 8024
    b.__sizeof__() # 9088

    由于元组操作的大小较小,因此它变得更快一些,但是在您拥有大量元素之前,不必多说。

  3. 允许的操作

    b    = [1,2]   
    b[0] = 3       # [3, 2]
    
    a    = (1,2)
    a[0] = 3       # Error

    这也意味着您不能删除元素或对元组进行排序。但是,您可以在列表和元组中都添加一个新元素,唯一的区别是,由于元组是不可变的,因此您并不是真正在添加元素,而是要创建一个新的元组,因此id将会改变

    a     = (1,2)
    b     = [1,2]  
    
    id(a)          # 140230916716520
    id(b)          # 748527696
    
    a   += (3,)    # (1, 2, 3)
    b   += [3]     # [1, 2, 3]
    
    id(a)          # 140230916878160
    id(b)          # 748527696
  4. 用法

    由于列表是可变的,因此不能用作字典中的键,而可以使用元组。

    a    = (1,2)
    b    = [1,2] 
    
    c = {a: 1}     # OK
    c = {b: 1}     # Error

Difference between list and tuple

  1. Literal

    someTuple = (1,2)
    someList  = [1,2] 
    
  2. Size

    a = tuple(range(1000))
    b = list(range(1000))
    
    a.__sizeof__() # 8024
    b.__sizeof__() # 9088
    

    Due to the smaller size of a tuple operation, it becomes a bit faster, but not that much to mention about until you have a huge number of elements.

  3. Permitted operations

    b    = [1,2]   
    b[0] = 3       # [3, 2]
    
    a    = (1,2)
    a[0] = 3       # Error
    

    That also means that you can’t delete an element or sort a tuple. However, you could add a new element to both list and tuple with the only difference that since the tuple is immutable, you are not really adding an element but you are creating a new tuple, so the id of will change

    a     = (1,2)
    b     = [1,2]  
    
    id(a)          # 140230916716520
    id(b)          # 748527696
    
    a   += (3,)    # (1, 2, 3)
    b   += [3]     # [1, 2, 3]
    
    id(a)          # 140230916878160
    id(b)          # 748527696
    
  4. Usage

    As a list is mutable, it can’t be used as a key in a dictionary, whereas a tuple can be used.

    a    = (1,2)
    b    = [1,2] 
    
    c = {a: 1}     # OK
    c = {b: 1}     # Error
    

回答 2

如果您去散散步,您可以随时在 (x,y)元组中。

如果要记录您的旅程,可以每隔几秒钟将您的位置附加到一个列表中。

但您无法做到这一点。

If you went for a walk, you could note your coordinates at any instant in an (x,y) tuple.

If you wanted to record your journey, you could append your location every few seconds to a list.

But you couldn’t do it the other way around.


回答 3

关键区别在于元组是不可变的。这意味着一旦创建元组,就无法更改其值。

因此,如果您需要更改值,请使用列表。

对元组的好处:

  1. 性能略有改善。
  2. 由于元组是不可变的,因此可以将其用作字典中的键。
  3. 如果您无法更改它,那么其他任何人也不能更改它,也就是说,您无需担心任何API函数等。无需询问即可更改元组。

The key difference is that tuples are immutable. This means that you cannot change the values in a tuple once you have created it.

So if you’re going to need to change the values use a List.

Benefits to tuples:

  1. Slight performance improvement.
  2. As a tuple is immutable it can be used as a key in a dictionary.
  3. If you can’t change it neither can anyone else, which is to say you don’t need to worry about any API functions etc. changing your tuple without being asked.

回答 4

列表是可变的;元组不是。

来自docs.python.org/2/tutorial/datastructures.html

元组是不可变的,通常包含一个异类元素序列,这些元素可以通过拆包(请参阅本节后面的内容)或索引(甚至在命名元组的情况下通过属性)进行访问。列表是可变的,并且它们的元素通常是同类的,并且可以通过遍历列表来访问。

Lists are mutable; tuples are not.

From docs.python.org/2/tutorial/datastructures.html

Tuples are immutable, and usually contain an heterogeneous sequence of elements that are accessed via unpacking (see later in this section) or indexing (or even by attribute in the case of namedtuples). Lists are mutable, and their elements are usually homogeneous and are accessed by iterating over the list.


回答 5

被提及的差异主要语义:人们期待一个元组和列表来表示不同的信息。但这远远超出了指导原则。有些库实际上根据传递的内容而有所不同。以NumPy为例(从我要求更多示例的另一篇文章中复制):

>>> import numpy as np
>>> a = np.arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> idx = (1,1)
>>> a[idx]
4
>>> idx = [1,1]
>>> a[idx]
array([[3, 4, 5],
       [3, 4, 5]])

关键是,虽然NumPy可能不是标准库的一部分,但它是一个主要的 Python库,在NumPy列表和元组中是完全不同的东西。

It’s been mentioned that the difference is largely semantic: people expect a tuple and list to represent different information. But this goes further than a guideline; some libraries actually behave differently based on what they are passed. Take NumPy for example (copied from another post where I ask for more examples):

>>> import numpy as np
>>> a = np.arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> idx = (1,1)
>>> a[idx]
4
>>> idx = [1,1]
>>> a[idx]
array([[3, 4, 5],
       [3, 4, 5]])

The point is, while NumPy may not be part of the standard library, it’s a major Python library, and within NumPy lists and tuples are completely different things.


回答 6

列表用于循环,元组用于结构,即"%s %s" %tuple

列表通常是同质的,元组通常是异类的。

列表用于可变长度,元组用于固定长度。

Lists are for looping, tuples are for structures i.e. "%s %s" %tuple.

Lists are usually homogeneous, tuples are usually heterogeneous.

Lists are for variable length, tuples are for fixed length.


回答 7

这是Python列表的示例:

my_list = [0,1,2,3,4]
top_rock_list = ["Bohemian Rhapsody","Kashmir","Sweet Emotion", "Fortunate Son"]

这是Python元组的示例:

my_tuple = (a,b,c,d,e)
celebrity_tuple = ("John", "Wayne", 90210, "Actor", "Male", "Dead")

Python列表和元组的相似之处在于它们都是值的有序集合。除了使用括号“ […,…]”创建列表的浅层差异以及使用括号“(…,…)”创建的元组之外,它们之间的核心技术“用Python语法进行硬编码”之间的差异是特定元组的元素是不可变的,而列表是可变的(…因此,只有元组是可哈希的,并且可以用作字典/哈希键!)。这就导致了它们的使用方式或不使用方式的差异(通过语法先验地实现)以及人们选择使用它们的方式上的差异(鼓励作为“最佳实践”,后验,这就是智能程序员所做的事情)。 人们赋予元素顺序。

对于元组,“顺序”仅表示存储信息的特定“结构”。在第一个字段中找到的值可以很容易地切换到第二个字段,因为每个值都提供跨两个不同维度或比例的值。它们为不同类型的问题提供答案,并且通常采用以下形式:对于给定的对象/对象,其属性是什么?对象/对象保持不变,属性不同。

对于列表,“顺序”表示顺序或方向。第二个元素必须位于第一个元素之后,因为它基于特定且通用的比例或维度位于第二位。这些元素是一个整体,并且通常针对一个给定属性的形式单个问题提供答案,对于给定的属性,这些对象/对象如何比较?属性保持不变,对象/主题不同。

有无数流行文化的人和不符合这些差异的程序员的例子,有无数人可能在主菜上使用色叉。一天结束后,一切都很好,通常都可以完成工作。

总结一些更好的细节

相似之处:

  1. 重复项 -元组和列表都允许重复项
  2. 索引,选择和切片 -元组和列表都使用括号内的整数值进行索引。因此,如果要给定列表或元组的前三个值,语法将是相同的:

    >>> my_list[0:3]
    [0,1,2]
    >>> my_tuple[0:3]
    [a,b,c]
  3. 比较和排序 -两个元组或两个列表都通过它们的第一个元素进行比较,如果有平局,则通过第二个元素进行比较,依此类推。在较早的元素显示出不同之后,不再关注后续元素。

    >>> [0,2,0,0,0,0]>[0,0,0,0,0,500]
    True
    >>> (0,2,0,0,0,0)>(0,0,0,0,0,500)
    True

区别: -先验,根据定义

  1. 语法 -列表使用[],元组使用()

  2. 可变性 -给定列表中的元素是可变的,给定元组中的元素不是可变的。

    # Lists are mutable:
    >>> top_rock_list
    ['Bohemian Rhapsody', 'Kashmir', 'Sweet Emotion', 'Fortunate Son']
    >>> top_rock_list[1]
    'Kashmir'
    >>> top_rock_list[1] = "Stairway to Heaven"
    >>> top_rock_list
    ['Bohemian Rhapsody', 'Stairway to Heaven', 'Sweet Emotion', 'Fortunate Son']
    
    # Tuples are NOT mutable:       
    >>> celebrity_tuple
    ('John', 'Wayne', 90210, 'Actor', 'Male', 'Dead')
    >>> celebrity_tuple[5]
    'Dead'
    >>> celebrity_tuple[5]="Alive"
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment
  3. 哈希表(字典) -由于哈希表(字典)要求其键是可哈希的,因此是不可变的,因此只有元组可以用作字典键,而不能用作列表。

    #Lists CAN'T act as keys for hashtables(dictionaries)
    >>> my_dict = {[a,b,c]:"some value"}
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    
    #Tuples CAN act as keys for hashtables(dictionaries)
    >>> my_dict = {("John","Wayne"): 90210}
    >>> my_dict
    {('John', 'Wayne'): 90210}

差异-后验用法

  1. 元素的均质性与异质性-通常,列表对象是同质的,而元组对象是异质的。也就是说,列表用于相同类型的对象/对象(例如所有总统候选人,所有歌曲或所有跑步者),而虽然不是强制的,但元组更多地用于异构对象。

  2. 循环与结构-尽管两者都允许循环(对于my_list中的x,…),但实际上对于列表而言才有意义。元组更适合于结构化和呈现信息(驻留在%s中的%s%s是%s,当前是%s%(“ John”,“ Wayne”,90210,“ Actor”,“ Dead”))

This is an example of Python lists:

my_list = [0,1,2,3,4]
top_rock_list = ["Bohemian Rhapsody","Kashmir","Sweet Emotion", "Fortunate Son"]

This is an example of Python tuple:

my_tuple = (a,b,c,d,e)
celebrity_tuple = ("John", "Wayne", 90210, "Actor", "Male", "Dead")

Python lists and tuples are similar in that they both are ordered collections of values. Besides the shallow difference that lists are created using brackets “[ … , … ]” and tuples using parentheses “( … , … )”, the core technical “hard coded in Python syntax” difference between them is that the elements of a particular tuple are immutable whereas lists are mutable (…so only tuples are hashable and can be used as dictionary/hash keys!). This gives rise to differences in how they can or can’t be used (enforced a priori by syntax) and differences in how people choose to use them (encouraged as ‘best practices,’ a posteriori, this is what smart programers do). The main difference a posteriori in differentiating when tuples are used versus when lists are used lies in what meaning people give to the order of elements.

For tuples, ‘order’ signifies nothing more than just a specific ‘structure’ for holding information. What values are found in the first field can easily be switched into the second field as each provides values across two different dimensions or scales. They provide answers to different types of questions and are typically of the form: for a given object/subject, what are its attributes? The object/subject stays constant, the attributes differ.

For lists, ‘order’ signifies a sequence or a directionality. The second element MUST come after the first element because it’s positioned in the 2nd place based on a particular and common scale or dimension. The elements are taken as a whole and mostly provide answers to a single question typically of the form, for a given attribute, how do these objects/subjects compare? The attribute stays constant, the object/subject differs.

There are countless examples of people in popular culture and programmers who don’t conform to these differences and there are countless people who might use a salad fork for their main course. At the end of the day, it’s fine and both can usually get the job done.

To summarize some of the finer details

Similarities:

  1. Duplicates – Both tuples and lists allow for duplicates
  2. Indexing, Selecting, & Slicing – Both tuples and lists index using integer values found within brackets. So, if you want the first 3 values of a given list or tuple, the syntax would be the same:

    >>> my_list[0:3]
    [0,1,2]
    >>> my_tuple[0:3]
    [a,b,c]
    
  3. Comparing & Sorting – Two tuples or two lists are both compared by their first element, and if there is a tie, then by the second element, and so on. No further attention is paid to subsequent elements after earlier elements show a difference.

    >>> [0,2,0,0,0,0]>[0,0,0,0,0,500]
    True
    >>> (0,2,0,0,0,0)>(0,0,0,0,0,500)
    True
    

Differences: – A priori, by definition

  1. Syntax – Lists use [], tuples use ()

  2. Mutability – Elements in a given list are mutable, elements in a given tuple are NOT mutable.

    # Lists are mutable:
    >>> top_rock_list
    ['Bohemian Rhapsody', 'Kashmir', 'Sweet Emotion', 'Fortunate Son']
    >>> top_rock_list[1]
    'Kashmir'
    >>> top_rock_list[1] = "Stairway to Heaven"
    >>> top_rock_list
    ['Bohemian Rhapsody', 'Stairway to Heaven', 'Sweet Emotion', 'Fortunate Son']
    
    # Tuples are NOT mutable:       
    >>> celebrity_tuple
    ('John', 'Wayne', 90210, 'Actor', 'Male', 'Dead')
    >>> celebrity_tuple[5]
    'Dead'
    >>> celebrity_tuple[5]="Alive"
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment
    
  3. Hashtables (Dictionaries) – As hashtables (dictionaries) require that its keys are hashable and therefore immutable, only tuples can act as dictionary keys, not lists.

    #Lists CAN'T act as keys for hashtables(dictionaries)
    >>> my_dict = {[a,b,c]:"some value"}
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    
    #Tuples CAN act as keys for hashtables(dictionaries)
    >>> my_dict = {("John","Wayne"): 90210}
    >>> my_dict
    {('John', 'Wayne'): 90210}
    

Differences – A posteriori, in usage

  1. Homo vs. Heterogeneity of Elements – Generally list objects are homogenous and tuple objects are heterogeneous. That is, lists are used for objects/subjects of the same type (like all presidential candidates, or all songs, or all runners) whereas although it’s not forced by), whereas tuples are more for heterogenous objects.

  2. Looping vs. Structures – Although both allow for looping (for x in my_list…), it only really makes sense to do it for a list. Tuples are more appropriate for structuring and presenting information (%s %s residing in %s is an %s and presently %s % (“John”,”Wayne”,90210, “Actor”,”Dead”))


回答 8

list的值可以随时更改,但是元组的值不能更改。

优点和缺点取决于使用。如果您拥有从未更改过的数据,则必须使用元组,否则list是最佳选择。

The values of list can be changed any time but the values of tuples can’t be change.

The advantages and disadvantages depends upon the use. If you have such a data which you never want to change then you should have to use tuple, otherwise list is the best option.


回答 9

列表和元组之间的区别

元组和列表在Python中似乎都是相似的序列类型。

  1. 文字语法

    我们使用括号()构造元组和方括号[ ]以获取新列表。另外,我们可以使用适当类型的调用来获取所需的结构-元组或列表。

    someTuple = (4,6)
    someList  = [2,6] 
  2. 变异性

    元组是不可变的,而列表是可变的。这是以下几点的基础。

  3. 内存使用情况

    由于可变性,您需要更多的内存用于列表,而更少的内存用于元组。

  4. 延伸

    您可以将新元素添加到元组和列表中,唯一的区别是将更改元组的ID(即,我们将有一个新的对象)。

  5. 散列

    元组可散列,而列表则不可。这意味着您可以将元组用作字典中的键。该列表不能用作字典中的键,而可以使用元组

    tup      = (1,2)
    list_    = [1,2] 
    
    c = {tup   : 1}     # ok
    c = {list_ : 1}     # error
  6. 语义学

    这一点是关于最佳实践的。您应该将元组用作异构数据结构,而列表则是同质序列。

Difference between list and tuple

Tuples and lists are both seemingly similar sequence types in Python.

  1. Literal syntax

    We use parenthesis () to construct tuples and square brackets [ ] to get a new list. Also, we can use call of the appropriate type to get required structure — tuple or list.

    someTuple = (4,6)
    someList  = [2,6] 
    
  2. Mutability

    Tuples are immutable, while lists are mutable. This point is the base the for the following ones.

  3. Memory usage

    Due to mutability, you need more memory for lists and less memory for tuples.

  4. Extending

    You can add a new element to both tuples and lists with the only difference that the id of the tuple will be changed (i.e., we’ll have a new object).

  5. Hashing

    Tuples are hashable and lists are not. It means that you can use a tuple as a key in a dictionary. The list can’t be used as a key in a dictionary, whereas a tuple can be used

    tup      = (1,2)
    list_    = [1,2] 
    
    c = {tup   : 1}     # ok
    c = {list_ : 1}     # error
    
  6. Semantics

    This point is more about best practice. You should use tuples as heterogeneous data structures, while lists are homogenous sequences.


回答 10

列表旨在为同质序列,而元组为异构数据结构。

Lists are intended to be homogeneous sequences, while tuples are heterogeneous data structures.


回答 11

正如人们已经在这里回答的那样tuples,虽然lists可变但可变是不变的,但是使用元组有一个重要方面,我们必须记住

如果中tuple包含一个listdictionary内部,则即使它们tuple本身是不可变的,也可以更改它们。

例如,假设我们有一个元组,其中包含一个列表和一个字典,如下所示

my_tuple = (10,20,30,[40,50],{ 'a' : 10})

我们可以将列表的内容更改为

my_tuple[3][0] = 400
my_tuple[3][1] = 500

这使得新的元组看起来像

(10, 20, 30, [400, 500], {'a': 10})

我们也可以将元组中的字典更改为

my_tuple[4]['a'] = 500

这将使整个元组看起来像

(10, 20, 30, [400, 500], {'a': 500})

这是因为 listdictionary是对象,而这些对象并没有改变,而是其指向的内容。

因此,这些tuple遗物毫无exceptions地保持不变

As people have already answered here that tuples are immutable while lists are mutable, but there is one important aspect of using tuples which we must remember

If the tuple contains a list or a dictionary inside it, those can be changed even if the tuple itself is immutable.

For example, let’s assume we have a tuple which contains a list and a dictionary as

my_tuple = (10,20,30,[40,50],{ 'a' : 10})

we can change the contents of the list as

my_tuple[3][0] = 400
my_tuple[3][1] = 500

which makes new tuple looks like

(10, 20, 30, [400, 500], {'a': 10})

we can also change the dictionary inside tuple as

my_tuple[4]['a'] = 500

which will make the overall tuple looks like

(10, 20, 30, [400, 500], {'a': 500})

This happens because list and dictionary are the objects and these objects are not changing, but the contents its pointing to.

So the tuple remains immutable without any exception


回答 12

PEP 484 -类型提示说,该类型的元素tuple可以单独输入; 这样你可以说Tuple[str, int, float]; 但是list,随着List键入类可以采取仅一种类型的参数:List[str],这提示了2的差异确实是,前者是异质的,而后者本质上是均匀的。

另外,标准库通常使用元组作为C会返回a的标准函数的返回值struct

The PEP 484 — Type Hints says that the types of elements of a tuple can be individually typed; so that you can say Tuple[str, int, float]; but a list, with List typing class can take only one type parameter: List[str], which hints that the difference of the 2 really is that the former is heterogeneous, whereas the latter intrinsically homogeneous.

Also, the standard library mostly uses the tuple as a return value from such standard functions where the C would return a struct.


回答 13

正如人们已经提到的差异一样,我将写有关元组的原因。

为什么首选元组?

小元组的分配优化

为了减少内存碎片并加快分配速度,Python重用了旧的元组。如果不再需要一个元组,并且元组少于20个,而不是将其永久删除,Python会将其移至空闲列表。

一个空闲列表分为20组,其中每个组代表长度为n的0至20之间的元组列表。每个组最多可以存储2000个元组。第一个(零)组仅包含一个元素,代表一个空的元组。

>>> a = (1,2,3)
>>> id(a)
4427578104
>>> del a
>>> b = (1,2,4)
>>> id(b)
4427578104

在上面的示例中,我们可以看到a和b具有相同的ID。那是因为我们立即占领了一个在空闲列表中的被破坏的元组。

列表分配优化

由于可以修改列表,因此Python不会使用与元组相同的优化。但是,Python列表也有一个空闲列表,但仅用于空对象。如果GC删除或收集了一个空列表,则以后可以重复使用。

>>> a = []
>>> id(a)
4465566792
>>> del a
>>> b = []
>>> id(b)
4465566792

资料来源:https : //rushter.com/blog/python-lists-and-tuples/

为什么元组比列表高效?-> https://stackoverflow.com/a/22140115

As people have already mentioned the differences I will write about why tuples.

Why tuples are preferred?

Allocation optimization for small tuples

To reduce memory fragmentation and speed up allocations, Python reuses old tuples. If a tuple no longer needed and has less than 20 items instead of deleting it permanently Python moves it to a free list.

A free list is divided into 20 groups, where each group represents a list of tuples of length n between 0 and 20. Each group can store up to 2 000 tuples. The first (zero) group contains only 1 element and represents an empty tuple.

>>> a = (1,2,3)
>>> id(a)
4427578104
>>> del a
>>> b = (1,2,4)
>>> id(b)
4427578104

In the example above we can see that a and b have the same id. That is because we immediately occupied a destroyed tuple which was on the free list.

Allocation optimization for lists

Since lists can be modified, Python does not use the same optimization as in tuples. However, Python lists also have a free list, but it is used only for empty objects. If an empty list is deleted or collected by GC, it can be reused later.

>>> a = []
>>> id(a)
4465566792
>>> del a
>>> b = []
>>> id(b)
4465566792

Source: https://rushter.com/blog/python-lists-and-tuples/

Why tuples are efficient than lists? -> https://stackoverflow.com/a/22140115


回答 14

5.3文档中的方向引文元组和序列

尽管元组看起来类似于列表,但是它们通常用于不同的情况和不同的目的。元组是不可变的,并且通常包含异类元素序列,这些元素可以通过拆包(请参阅本节后面的内容)或索引(甚至在namedtuple的情况下通过属性)进行访问。列表是可变的,并且它们的元素通常是同质的,可以通过迭代列表来访问。

A direction quotation from the documentation on 5.3. Tuples and Sequences:

Though tuples may seem similar to lists, they are often used in different situations and for different purposes. Tuples are immutable, and usually contain a heterogeneous sequence of elements that are accessed via unpacking (see later in this section) or indexing (or even by attribute in the case of namedtuples). Lists are mutable, and their elements are usually homogeneous and are accessed by iterating over the list.


回答 15

首先,它们都是Python中的非标量对象(也称为复合对象)。

  • 元组,元素的有序序列(可以包含任何对象,而不会出现别名问题)
    • 不可变的(元组,整数,浮点数,str)
    • 使用串联+(当然会创建全新的元组)
    • 索引编制
    • 切片
    • 单例(3,) # -> (3)而不是(3) # -> 3
  • 列表(其他语言的数组),值的有序序列
    • 可变的
    • 辛格尔顿 [3]
    • 克隆 new_array = origin_array[:]
    • 列表理解[x**2 for x in range(1,7)]给您 [1,4,9,16,25,36](不可读)

使用列表可能还会导致混淆错误(指向同一对象的两个不同路径)。

First of all, they both are the non-scalar objects (also known as a compound objects) in Python.

  • Tuples, ordered sequence of elements (which can contain any object with no aliasing issue)
    • Immutable (tuple, int, float, str)
    • Concatenation using + (brand new tuple will be created of course)
    • Indexing
    • Slicing
    • Singleton (3,) # -> (3) instead of (3) # -> 3
  • List (Array in other languages), ordered sequence of values
    • Mutable
    • Singleton [3]
    • Cloning new_array = origin_array[:]
    • List comprehension [x**2 for x in range(1,7)] gives you [1,4,9,16,25,36] (Not readable)

Using list may also cause an aliasing bug (two distinct paths pointing to the same object).


回答 16

列表是可变的,元组是不可变的。只要考虑这个例子。

a = ["1", "2", "ra", "sa"]    #list
b = ("1", "2", "ra", "sa")    #tuple

现在更改list和tuple的索引值。

a[2] = 1000
print a     #output : ['1', '2', 1000, 'sa']
b[2] = 1000
print b     #output : TypeError: 'tuple' object does not support item assignment.

因此证明了以下代码对元组无效,因为我们试图更新一个元组,这是不允许的。

Lists are mutable and tuples are immutable. Just consider this example.

a = ["1", "2", "ra", "sa"]    #list
b = ("1", "2", "ra", "sa")    #tuple

Now change index values of list and tuple.

a[2] = 1000
print a     #output : ['1', '2', 1000, 'sa']
b[2] = 1000
print b     #output : TypeError: 'tuple' object does not support item assignment.

Hence proved the following code is invalid with tuple, because we attempted to update a tuple, which is not allowed.


回答 17

列表是可变的,元组是不可变的。可变项和不可变项之间的主要区别是在尝试附加项目时的内存使用情况。

创建变量时,会将一些固定内存分配给该变量。如果是列表,则分配的内存将大于实际使用的内存。例如,如果当前内存分配为100字节,则当您要追加第101个字节时,可能会另外分配100个字节(在这种情况下,总共为200个字节)。

但是,如果您知道不经常添加新元素,则应使用元组。元组精确分配所需的内存大小,从而节省了内存,尤其是在使用大容量内存块时。

List is mutable and tuples is immutable. The main difference between mutable and immutable is memory usage when you are trying to append an item.

When you create a variable, some fixed memory is assigned to the variable. If it is a list, more memory is assigned than actually used. E.g. if current memory assignment is 100 bytes, when you want to append the 101th byte, maybe another 100 bytes will be assigned (in total 200 bytes in this case).

However, if you know that you are not frequently add new elements, then you should use tuples. Tuples assigns exactly size of the memory needed, and hence saves memory, especially when you use large blocks of memory.