关于列表的Python 3其他问题

时间:2018-07-09 16:56:59

标签: python python-3.x

我有两个不相关的问题,它们也不是至关重要的:


问题1:

x,y = 1,2这样的单行声明的顺序是什么?首先声明x还是首先声明y?例如,当xy通过引用关联时。


问题2:

假设我有一个像这样的linkedList声明:

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

我有一个ListNode的列表,如:

lists = [1->2->3, 2->3->1, 0->9]

如果我想继续比较每个ListNode的第一个值并找到最小的值,我可以这样做:

smallest_index = 0
for index in range(len(lists)):
    if lists[index].val < lists[smallest_index].val:
        smallest_index = index

但是有更好的方法吗?使用内置函数来减少行数的更“优雅”的方式?

2 个答案:

答案 0 :(得分:1)

关于您的第一个问题,作业既一次执行,又从左至右执行。从Python的角度以及您无权访问的环境中,您可以一次在引擎盖下从左到右访问字节环境。您可以使用dis模块进行检查。

In [1]: x,y = 1,2

In [2]: import dis

In [3]: dis.dis('x,y = 1,2')
  1           0 LOAD_CONST               3 ((1, 2))
              3 UNPACK_SEQUENCE          2
              6 STORE_NAME               0 (x)
              9 STORE_NAME               1 (y)
             12 LOAD_CONST               2 (None)
             15 RETURN_VALUE

如您所见,首先在偏移量6处定义变量x,然后在偏移量9处定义y。但是请注意,这并不意味着您可以在同一块中访问新任务。这就是说,在类似y, x = 9, y+1的代码中,y的值是赋值之前的值(如果已经声明)。出现这种现象的原因是,您在反汇编的字节码中看到的是在后台而不是在Python级别发生的事情,并且从您的角度来看,整个字节码将被立即评估。

关于第二个问题,您可以在min()函数中使用生成器表达式:

min(lst.val for lst in lists)

如果要返回Node对象,可以将operator.attrgetter()用作key函数。

min(lists, key=attrgetter('val'))

答案 1 :(得分:1)

问题1

同时有效地声明它们。如果要基于另一个值来确定一个值,则不应使用单行声明。

演示:

>>> x,y = 1,x+2    
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> x,y = 1,y+2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined

问题2

通常,您应该将可读性优先于优雅,但要回答您的问题,还有另一种方法可以完成您想做的事情。

请注意,此语法lists = [1->2->3, 2->3->1, 0->9]无效,所以我改为这样做:lists = [ListNode(1),ListNode(2),ListNod(3)]

from operator import attrgetter
min(nodes, key=attrgetter('val'))

这将返回具有最低val的ListNode。您可以调用.val来获取值本身。