python3中list列表的一些操作

  使用到了:+, append(), extend(), insert()

列表的问题3

给定n个数的列表,使用单列表理解来生成只包含如下这些值的新列表。

  1. 偶数
  2. 索引也是偶数

我们可以采用如下代码完成这个工作:

[x for x in my_list[::2] if x % 2 == 0]

示例:

my_list = [ 1 , 3 , 5 , 8 , 10 , 13 , 18 , 36 , 78 ]
new_list = [x for x in my_list[::2] if x % 2 == 0]
#output:
[10, 18, 78]
lao zhang
a [123, 'abc', 12.3]
c [123, 'abc', 12.3]
True
b ['lao li', 'lao wang', 'lao liu']
d ['lao wang', 'lao liu']
False
e ['aabbcc', 223344]
f ['aabbcc', 223344]
e [223344]
False

列表的问题2

思考下面的代码片段:

1. list = [ [ ] ] * 5
2. list  # output?
3. list[0].append(10)
4. list  # output?
5. list[1].append(20)
6. list  # output?
7. list.append(30)
8. list  # output?

答案揭晓:

[[], [], [], [], []]
[[10], [10], [10], [10], [10]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30]

第一行的输出是直观的,也很容易理解,仅仅是创建了5个列表的列表。

但是,理解问题的关键是list = [ [ ] ] * 5并不是创建了5个不同的列表,而是对一个列表的5个引用,有了这层理解我们对下面的输出就好理解了。

list[0].append(10)在第一个列表中添加了元素10,
其他列表都是对同一个列表的引用,所以输出如上。

同样的道理,第二个列表添加了元素20,也是对同一个列表进行的操作。

相反,list.append(30)则是添加了一个元素到外层列表中,也就是说,
30是和剩下的5个列表同一层级的(个人理解)。所以输出如上。

# -*- coding: utf-8 -*-
"""
Created on Tue Aug  7 20:10:41 2018
@author: brave-man
blog: http://www.cnblogs.com/zrmw/
"""

a = [123, 'abc', 12.3, 'lao zhang']
b = ['lao li', 'lao wang', 'lao liu']

print(a + b)

a.extend(b)
print(a)

a.insert(0, b)
print(a)

a.append(b)
print(a)

类变量的问题

下面的代码会输出什么?请解释。

class Parent(object):
    x = 1

class ChildFirst(Parent):
    pass

class ChildSecond(Parent):
    pass

print(Parent.x, ChildFirst.x, ChildSecond.x)
ChildFirst.x = 2
print(Parent.x, ChildFirst.x, ChildSecond.x)
Parent.x = 3
print(Parent.x, ChildFirst.x, ChildSecond.x)

答案揭晓:

1 1 1
1 2 1
3 2 3

WTF? 为什么最后一行输出不是3 2 1而是3 2 3?
为什么改变了Parent.x的值竟然也改变了ChildSecond.x的值。但是却没有改变ChildFirst.x的值?

这个问题的答案的关键是: 在Python中,类变量在内部是作为字典来处理的。

如果一个变量名没有在当前类的变量字典中找到,就会去搜索父类的变量字典,如果在一直延续到在顶层的祖先类的字典中也没有找到该变量。就会报出一个AttributeError的异常。

因此,在Parent中设置了类变量x=1,在该类和其任何子类的的变量引用中生效x=1.这就是为什么第一行输出1 1 1

然后,如果某一个子类重写了这个变量,就像我们执行了ChildFirst.x=2,这个值会仅仅在这个子类中发生变化。这就是为什么第二行输出1 2 1

最后,如果在父类Parent中改变。就会使得所有没有重写这个变量的子类中的该变量的值发生变化。就是最后一行输出3 2 3的原因。

[123, 'abc', 12.3, 'lao zhang', 'lao li', 'lao wang', 'lao liu']
[123, 'abc', 12.3, 'lao zhang', 'lao li', 'lao wang', 'lao liu']
[['lao li', 'lao wang', 'lao liu'], 123, 'abc', 12.3, 'lao zhang', 'lao li', 'lao wang', 'lao liu']
[['lao li', 'lao wang', 'lao liu'], 123, 'abc', 12.3, 'lao zhang', 'lao li', 'lao wang', 'lao liu', ['lao li', 'lao wang', 'lao liu']]

参考文章

https://www.toptal.com/python/interview-questions
http://docs.python-guide.org/en/latest/writing/gotchas/

 

列表的问题1

下面代码会输出什么?

my_list = ["a", "b", "c", "d", "3"]
print(my_list[10:])

答案揭晓:

# output:
[]

上边的代码会输出[],而不是一个IndexError的异常。

正如人们所预料的,
试图使用超过成员数量的索引访问列表的成员(eg..my_list[10])会报出IndexError异常。

但是试图以一个超出列表成员数量的索引作为开始索引的切片操作不会导致下标异常,仅仅是返回一个空列表。

一个特别严重的问题是,它可能导致的错误,但是很难追踪到,因为它并没有出现运行错误。

最近遇到许多List的操作,感觉它是一种很重要的一种基础数据结构,本人掌握的也不是很扎实,这里找了一些列表的操作,常用函数,记录下来,希望对大家有用。如果理解有偏差,欢迎指正,感谢!

简介

在Python中也会有很多陷阱,在网上看到一篇文章,在此处记录以下,菜鸡翻译。

        

问题集合

相关文章