http://blog.csdn.net/pipisorry/article/details/39234557

这篇文章是python基本数据结构的高级教程,一般的用法请自行参考python入门教程

python入门教程

基础

变量及其作用域

[python变量及其作用域,闭包 ]

[python数据类型的内存分析 ]

函数

[python函数: 内置函数  ]

运算符

Python运算符优先级

从最高到最低优先级的所有运算符

运算符 描述
** 指数 (最高优先级)
~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
* / % // 乘,除,取模和取整除
+ - 加法减法
>> << 右移,左移运算符
& 位 'AND'
^ | 位运算符
<= < > >= 比较运算符
<> == != 等于运算符
= %= /= //= -= += *= **= 赋值运算符
is is not 身份运算符
in not in 成员运算符
not or and 逻辑运算符(or和and同优先级!!!)

Note: 位运算符优先级相当低,所以位运算时记得加括号不出错。

逻辑运算符

在py2/py3中,and 和 or 执行布尔逻辑演算,但是它们并不返回布尔值,而是返回它们实际进行比较的值之一。

and 从左到右扫描,返回第一个为假的表达式值,无假值则返回最后一个表达式值。or 从左到右扫描,返回第一个为真的表达式值,无真值则返回最后一个表达式值!!!

因为在python中or和and同优先级,所以多个同时使用时一定要加上括号,如a and b or c不是a为false就返回false的!!!只使用一个就不需要括号。

>>> '' and 'b'
''
>>> 'a' and 'b' and 'c'
'c'
>>> '' or 'b'
'b'
>>> '' or [] or{}
{}

and-or搭配使用:

>>> a = "betabin"
>>> b = "python"
>>> 1 and a or b
'betabin'
>>> 0 and a or b
'python'

看起来类似于于我们C++中的条件运算符(bool?a:b),是的,当a为true的时候是一样的。但是,当a为false的时候,就明显不同了。如果坚持要用and-or技巧来实现条件运算符的话,可以用种安全的方法:

>>> a = ""
>>> b = "betabin"
>>> (1 and [a] or [b])[0]
''

就是万能的[],把a为假的可能性给抹杀掉,然后通过[0]再获得(因为要通过[0]获得元素,所以b也得加上[])。这个and-or技巧主要在lambda中使用。

python除法

python2除法真是个大坑!

具体参考4)整型除法返回浮点数,要得到整型结果,请使用// [python2和python3的区别、转换及共存]

比较

python中运算符‘is’,'is not'和‘==’,’!=‘的区别
is,is not是地址比较
==,!= 是值比较

值和地址的比较

常量的地址是不变的:

k = -1
k == -1 True k is -1 True

列表就不是常量了

a = [123.4, 234.4]
b = [123.4, 234.4]
print(a == b)
True
print(a is b)
False

学习资源

[慕课网Python教程]

[简明Python教程]

[Python基本语法[二],python入门到精通[四]]

[python有哪些好的学习资料或者博客?]

[[译]学习Python编程的19个资源]

[为什么Python中没有Switch/Case语句?]

[StarterLearningPython]

[Python 初学者的最佳学习资源]

[我是如何开始学Python的]

[学习Python的三种境界]lz感觉自己到了境界2,哈哈!!

python高级基础:python语法糖

Python实现两个变量值交换

a,b = b,a

if else表达式

fpython没有三目运算符,我挺苦恼的,比如把两个整数较大的那个复制给一个变量,有三目运算符的语言会这样写:
c = a > b ? a : b
后来发现Python的if语句可以写成一行完成上述功能:
c = a if a > b else b

执行字符串表达式eval

eval执行一个字符串表达式,并返回表达式的值。
print eval("1 + 1")
>> 2
再来个复杂点的:
def init():
    return 1
def func(num):
    return 2
action = {"num": init, "func": func}
expression = 'func(num)'
print eval(expression, action)
>> 2

python for循环高级用法

for/else我们经常使用for循环来查找元素,有两个场景会使循环停下来:
元素被找到,触发break。
循环结束。
但是我们并不知道是哪个原因导致循环结束,通常是设置一个标记,元素被找到,改变标记的值。for/else可以很优雅地解决这个问题:
for i in range(10):
if i > 10:
    print i
else:
    print("can't find result")

在分支语句中使用else子句在一些常见的编程语言中的用法基本相同,类似于提供了一条默认的执行路径,配合if等条件判断语句使用,相比其它的编程语言(c#, java, js等)在python中,else有一些特殊的用法,配合for, while等循环语句使用,甚至还能配合异常处理try except语句进行使用,能够让我们的代码更加的简洁。

配合for/while循环语句使用
在for循环语句的后面紧接着else子句,在循环正常结束的时候(非return或者break等提前退出的情况下),else子句的逻辑就会被执行到。先来看一个例子:
def print_prime(n):
    for i in xrange(2, n):
        # found = True
        for j in xrange(2, i):
            if i % j == 0:
                 # found = False 
                break
        else:
            print "{} it's a prime number".format(i)
        # if found:
                  # print "{} it's a prime number".format(i)
print_prime(7)

2 it's a prime number
3 it's a prime number
5 it's a prime number
一个简单打印素数的例子,判断某个数字是否是素数的时候需要遍历比它自己小的整数,任何一个满足整除的情况则判断结束,否则打印这是一个素数的info,有了else的加持,整个例子的逻辑相当的“self-expressive”,如同伪代码一般的好理解而且相比在判断整除的时候设置标志值然后在函数的结尾处判断标志值决定是否打印数字时素数的消息,代码更简洁没有那么多要描述如何做的“过程式”准备工作。
大家可以把例子中的被注释代码运行对比下效果。

[配合 try except错误控制使用]

[善用python的else子句]

python跳出多层循环

1、自定义异常
class getoutofloop(Exception): pass
try:
    for i in range(5):
        for j in range(5):
            for k in range(5):
                if i == j == k == 3:
                    raise getoutofloop()
                else:
                    print i, '----', j, '----', k
except getoutofloop:
    pass
2、封装为函数return
def test():
    for i in range(5):
        for j in range(5):
            for k in range(5):
                if i == j == k == 3:
                    return
                else:
                    print i, '----', j, '----', k
test()
3、for … else … 用法
上面的两种都是只能跳出多层而不能跳出特定层数的循环,接下来的这个正是为了跳出特定层数的循环。
for i in range(5):
    for j in range(5):
        for k in range(5):
            if i == j == k == 3:
                break
            else:
                print i, '----', j, '----', k
        else: continue
        break
    else: continue
    break
else在 while和for 正常循环完成之后执行,和直接写在 while和for 之后没有区别,但是如果用break结束循环之后else就不会执行了。

不过要是有多次跳出不同层的循环的需求,也没辙了。

[How to break out of multiple loops in Python?]

[Breaking out of nested loops [duplicate]]

[break two for loops [duplicate]]

序列迭代

复杂迭代实例

test_dict = {(1, 2): [3, 4, 5]}
for e, (w, *f) in test_dict.items():print(e, w, f)
for e, w, *f in test_dict.items():print(e, w, f)

(1, 2) 3 [4, 5]
(1, 2) [3, 4, 5] []

反向迭代

对于普通的序列(列表),我们可以通过内置的reversed()函数进行反向迭代:
# 通过 reversed 进行反向迭代
for i in reversed(list_example):
    print(i)
# 但无法作用于 集合 和 迭代器
除此以外,还可以通过实现类里的__reversed__方法,将类进行反向迭代:
class Countdown:
    def __init__(self, start):
        self.start = start

# 正向迭代
    def __iter__(self):
        n = self.start
        while n > 0:
            yield n
            n -= 1

# 反向迭代
    def __reversed__(self):
        n = 1
        while n <= self.start:
            yield n
            n += 1

皮皮Blog

python列表list

在Python中,列表是一个动态的指针数组。[python数据类型的内存分析]

函数的默认参数一定不要设置为可变类型如list,否则会出现潜在的错误

参考[python函数 - 函数的参数]错误的示例

python列表的创建、插入、抛出、拆箱操作

创建

1 通过字符串创建

list( 'asdf')    #['a', 's', 'd', 'f']

2 其它数据类型如tuple的转换等等

3 创建一个m*n的2层全0元素的list

l = [[0 for in range(n)] for in range(m)]

一般不要使用l = [[0]*n]*m来创建,里面的数据是共享内存的,改动l[0][1]=2,则整个l[0]=[2,2,2,...]

list的插入操作是调用函数listinsert来实现的。

该函数的流程如下:

1、解析参数。

2、调用静态函数ins1进行插入操作。

list的插入操作对索引值的处理在函数ins1中进行,相关处理过程如下:

1、将列表的条目数赋值给n;
2、如果索引值小于0,则将索引值增加n;如果仍小于0,则将索引值赋值为0;
3、如果索引值大于n,则将索引值赋值为n。

list中添加元素

append 添加单个元素
list.append()返回None
如果代码全写在同一行如列表解析中,不想返回None而是返回添加后的列表,可以使用list + [元素]也就是list+list。
extend或者+= 添加多个元素/合并列表
list1.extend(list2) 或者 list1 += list2

抛出操作当条目索引为负数时的处理

list的抛出操作是将指定索引位置的条目从列表中删除并且返回该条目的值。list的抛出操作是调用函数listpop来实现的。

对索引值index的相关处理过程如下:

1、如果index小于0,则将index增加列表本身的条目数;

2、如果index仍小于0或大于列表条目数,则输出错误信息提示索引值超出范围。

源码中将操作位置初始化为-1,所以如果没有指定抛出位置,则默认抛出最后一个条目。

迭代

迭代列表中的每两个元素

lambda a, k:zip(*([iter(a)]*k))

[python函数: 内置函数]

拆箱

>>> a, b, c = [1,2,3]

>>> a, b, c

(1,2,3)

>>> a, b, c = (2*i+1foriinrange(3))

>>> a, b, c

(1,3,5)

>>> a, (b, c), d=[1, (2,3),4]

>>> a

1

>>> b

2

>>> c

3

>>> d

4

扩展的拆箱(Python 3支持)

>>> a, *b, c=[1,2,3,4,5]

>>> a

1

>>> b

[2,3,4]

>>> c

5

python列表查找、索引和统计

List slices with step (a[start:end:step])带步长列表切片

1 如果从列表开头开始切割,那么忽略 start 位的 0,例如list[:4];如果一直切到列表尾部,则忽略 end 位的 0,例如list[3:]。
2 切割列表时,即便 start 或者 end 索引跨界也不会有问题。正如人们所期望的,试图访问一个超过列表索引值的成员将导致 IndexError(比如访问以上列表的 list[10])。尽管如此,试图访问一个列表的以超出列表成员数作为开始索引的切片将不会导致 IndexError,并且将仅仅返回一个空列表。
3 列表切片不会改变原列表(都是浅拷贝)。索引都留空时,会生成一份原列表的浅拷贝。b = a[:]   assert b == a and b is not a # true。注意这个属性和numpy不一样,numpy中切片是多维数组对象的视图!

Note: b = a直接赋值的话,两个列表就是同一个列表,相当于视图,没有任何copy。[python模块 - copy模块]

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a[::2]
[0, 2, 4, 6, 8, 10]

list = ['a', 'b', 'c', 'd', 'e']
print list[10:]
以上代码将输出 [],并且不会导致一个 IndexError。

List slice assignment列表切片赋值

>>> a = [1, 2, 3, 4, 5]
>>> a[2:3] = [0, 0]
>>> a
[1, 2, 0, 0, 4, 5]
>>> a[1:1] = [8, 9]
>>> a
[1, 8, 9, 2, 0, 0, 4, 5]
>>> a[1:-1] = []
>>> a
[1, 5]

python列表取倒数n个数

a = [1,2,3,4,5,6]
print(a[-3:])

python列表反转

a = a[::-1]

切片命名(slice(start, end, step))

>>> a =[0,1,2,3,4,5]

>>> LASTTHREE = slice(-3,None)

>>> LASTTHREE

slice(-3,None,None)

>>> a[LASTTHREE]

[3,4,5]

python列表查找某个元素

list.index(索引内容, index_start=None, index_end=None)

1.

try:k = l.index(4)    #index查找不存在的元素会出异常
except:k = 3

比2好,不用搜索列表两次,更快。

2.

if 4 not in l:k = 3
else:k = l.index(4)

3. 如果列表元素很多(如大于10000),应先转换成字典再查找(更耗用内存),速度不只100倍的提升!

fs_dict = dict.fromkeys(fs_list, True)
[(u, v) for u, v in fs_dict]

最大和最小元素(heapq.nlargest andheapq.nsmallest)

>>> a = [random.randint(0, 100) for __ in range(100)]
>>> heapq.nsmallest(5, a)
[3, 3, 5, 6, 8]
>>> heapq.nlargest(5, a)
[100, 100, 99, 98, 98]

python列表统计

统计某个元素个数count()

list支持count方法

>>> a = ['a', 'b', 'c', 3, '4', '2', '2', 2, 2]
>>> a.count(2)
2
>>> a.count('a')
1
>>> a.count('d')
0

[True,True,False].count(True)
2

当然统计True,False这种可以使用sum方法

>>> l = [1, 2, True, False]
>>> sum(bool(x) for x in l)
3

统计列表中所有元素出现次数

使用pandas顶级函数pd.value_counts,value_counts是一个顶级pandas方法,可用于任何数组或序列:>>> pd.value_counts(obj.values, sort=False)

[pandas小记:pandas索引和选择]

比列表解析要快2倍以上(时间包含了列表转换成ndarray的时间,如果已经是ndarray要快10倍左右)。

paths_len_dict_list = {len: values.count(len) for len in set(values)}

其实最好用collections.Counter[python标准库:collections和heapq模块  ]

python列表删除操作

python列表中删除某个元素

使用del关键字删除指定位置的元素
input = [1,2,3,4]
del input[1]
使用pop方法删除指定位置的元素
input = [1,2,4,5,6]
input.pop(2)
注意list的pop方法如果指定参数的话,会删除指定索引位置的元素,如果未指定将删除list的最后一个元素。

python列表中删除某个元素所有的出现,如空字符串

while '' in classified_sentences:
classified_sentences.remove('')

python清空列表的几种方式

1. s.clear()

2. del s[:]

3. s[:] = []

4. s *= 0

python列表、元组排序

list.sort()一般用法:指定轴axis;自定义comparator函数key; 升降序选择reverse。

list.sort(axis = None, key=lambda x:x[1], reverse = True)

python列表拷贝

python中怎么对一个列表赋值并修改不影响原来的列表?

  1. 简单列表的拷贝

    已知一个列表,求生成一个新的列表,列表元素是原列表的复制

    a=[1,2]
    b=a

    这种其实并未真正生成一个新的列表,b指向的仍然是a所指向的对象。

    后果:如果对a或b的元素进行修改,a,b的值同时发生变化:a.remove(1)则对应b也变为[2]

  2. 可以使用以下方法解决

    a=[1,2]
    b=a[:]

    这样修改a对b没有影响。修改b对a没有影响。

  3. 列表拷贝

a = [1,2,3]

b = a.copy()

print(id(a), id(b))

4.复杂列表的拷贝

可以使用copy模块中的deepcopy函数。修改测试如下:

import copy
              a=[1,[2]]

b=copy.deepcopy(a)

[图解 Python 深拷贝和浅拷贝]

python两个列表的操作

python两个列表相减

方法1. 用set(集合)操作
list3 = list(set(list1) - set(list2))
set操作会将一个list转换成一个集合,重复的项会被删除。
方法2.列表解析

list3 = [i for i in list1 if i not in list2]
但是在list很大的时候,没有set方法快。

python中求两个list的交集,两个list是否有交集

list1 = [1,2]
list2 = [2,3]
print(set(list1).intersection(set(list2)))
{2}

python两个列表合并extend

list.extend(seq)
Note:在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)

返回none

如果不想改变原来list,可以用new_list = copy.deepcopy(list)

Flattening lists扁平列表

[Python模块 - itertools循环器模块]

python的for循环从两个不同列表中同时取出两个元素zip

zip(): 如果你多个等长的序列,然后想要每次循环时从各个序列分别取出一个元素,可以利用zip()方便地实现:

ta = [1,2,3]
tb = [9,8,7]
tc = ['a','b','c']
for (a,b,c) in zip(ta,tb,tc):print(a,b,c)

一个for循环中每次迭代输出两个列表对应的元素及对应的索引号enumerate&zip

users = [1,2,3]
items = [4,5,6]
for index, (user, item) in enumerate(zip(users, items)):print(index, user, item)
0 1 4
1 2 5
2 3 6

[python - 常用函数和全局变量--zip]

python列表其它操作

在python列表中每个元素间添加逗号,

(最后一个元素后面不加,,这里a中的元素必须是字符串)

a = ['12', '34', '45']
s = ','.join(a)
print(s)
12,34,45

当然如果x中的元素不是字符串可以先转换一下

[''.join(xi) for xi in np.array(x).astype(str)]

列表解析和条件表达式

列表解析( List comprehensions)

列表解析一般都是下面的形式

[expr for iter_var in iterable if cond_expr]

迭代iterable里所有内容,每一次迭代后,把iterable里满足cond_expr条件的内容放到iter_var中,再在表达式expr中应该iter_var的内容,最后用表达式的计算值生成一个列表。

Note: iterable不能是None类型,否则会报错:notype is not iterable。

# times even numbers by 2 and odd numbers by 3

mul = [num * 3 if num % 2 else num * 2 for num in numbers]

如果没有else语句,只能将if语句放到后面

jiebaWords = [i for i in jiebaWords if len(i) >= 2]

虽然列表解析比for循环快很多,但是其实也没那么快,如

c = (np.array(a) ** 2).sum()
b = sum([i ** 2 for i in a])

numpy的计算比列表解析快4倍,甚至c = np.sum(np.array(a)); b = sum(a);都比列表的直接计算sum快一丢丢。

Note: 数据多时,列表推导式可能会消耗大量内存,此时建议使用生成器表达式。

列表解析的顺序

[[i+j for i in 'abc'] for j in "def"]

先算内部的,结果为:[['a'+j,'b'+j,'c'+j] for j in "def"]
再算外部的,结果为:[['a'+'d','b'+'d','c'+'d'],['a'+'e','b'+'e','c'+'e'],['a'+'f','b'+'f','c'+'f']]
所以输出为:[[‘ad’, ‘bd’, ‘cd’], [‘ae’, ‘be’, ‘ce’], [‘af’, ‘bf’, ‘cf’]]

列表解析加速

列表解析中调用函数

lz提示,千万不要在列表解析中使用计算时间长的函数或者什么的,这样每次for解析时都会重新调用一次那个函数。所以不要过于依赖列表解析的代码简洁性。

It is very complex for the compiler/interpreter to determine that the function need not to be called many times. It is then very probable that the function is called many times.

[function inside list comprehension - is it evaluated multiple times [duplicate]]

列表解析的其它可参考优化

使用列表解析时,if语句中有in list语句时

[Python性能优化 ]

python列表和json格式的相互转换

[python对象与json的转换 ]

list实现栈

use a list as a stack: #像栈一样使用列表
stack = [3, 4, 5]
stack.append(6)
stack.append(7)
stack
[3, 4, 5, 6, 7]
stack.pop() #删除最后一个对象
7
stack
[3, 4, 5, 6]
stack.pop()
6
stack.pop()
5
stack
[3, 4]

队列实现

use a list as a queue: #像队列一样使用列表
> from collections import deque #这里需要使用模块deque
> queue = deque(["Eric", "John", "Michael"])
> queue.append("Terry")           # Terry arrives
> queue.append("Graham")          # Graham arrives
> queue.popleft()                 # The first to arrive now leaves
'Eric'
> queue.popleft()                 # The second to arrive now leaves
'John'
> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

皮皮Blog

python元组操作

1个元素的tuple

元组中只包含一个元素时,需要在元素后面添加逗号来消除歧义tup1 = (50,)

要定义一个只有1个元素的tuple,如果你这么定义:
>>> t = (1)
>>> t
1
定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1。

元组连接组合

元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');
# 以下修改元组元素操作是非法的。
# tup1[0] = 100;
# 创建一个新的元组
tup3 = tup1 + tup2;
print tup3;
#(12, 34.56, 'abc', 'xyz')

一个“可变的”tuple

t = ('a', 'b', ['A', 'B'])
t[2].append(1)
t[2][1] = 2
print(t)
('a', 'b', ['A', 2, 1])

当然tuple中如果存在可变的元素后就不能使用dict类型的key了。

命名元组namedtuple

因为 tuple 作为没有名字的记录来使用在某些场景有一定的局限性,所以又有了一个 namedtuple 类型的存在,namedtuple 可以指定字段名,用来当做一种轻量级的类来使用。

[命名的tuples(collections.namedtuple)]

python列表和元组的区别和联系

相同点:

列表与元组都是序列类型,都是序列类型的容器对象,可以存放任何类型的数据、支持切片、迭代等操作。二者都可以包含任意类型的元素甚至可以是一个序列,还可以包含元素的顺序(不像集合和字典)。

异点:

两种类型除了字面上的区别(括号与方括号)之外,最重要的一点是tuple是不可变类型,大小固定,而 list 是可变类型、数据可以动态变化,这种差异使得两者提供的方法、应用场景、性能上都有很大的区别。

1 列表特有方法所有的操作都基于原来列表进行更新,而 tuple 作为一种不可变的数据类型,同样大小的数据,初始化和迭代 tuple 都要快于 list。同样大小的数据,tuple 占用的内存空间更少。

2 原子性的 tuple 对象还可作为字典的键。(例如上面的一个“可变的”tuple就不是原子性的,不能作为字典的键)。

3 同构 VS 异构

tuple 用于存储异构(heterogeneous)数据,当做没有字段名的记录来用,比如用 tuple 来记录一个人的身高、体重、年龄。person = ("zhangsan", 20, 180, 80)

而列表一般用于存储同构数据(homogenous),同构数据就是具有相同意义的数据,比如下面的都是字符串类型["zhangsan", "Lisi", "wangwu"]

再比如 list 存放的多条用户记录[("zhangsan", 20, 180, 80), ("wangwu", 20, 180, 80)]。数据库操作中查询出来的记录就是由元组构成的列表结构。

4 列表和元组的“技术差异”是,列表是可变的,而元组是不可变的。这是在 Python 语言中二者唯一的差别。比如:列表有一个 append() 的方法来添加更多的元素,而元组却没有这个方法。元组并不需要一个 append() 方法,因为元组不能修改。比如你不能把列表当做字典的关键字,因为只有不可变的值才能进行哈希运算,因此只有不可变的值才能作为关键字。要使用列表做关键字,你需要把它转化为元组。

5 “文化差异“是指二者在实际使用中的差异:在你有一些不确定长度的相同类型队列的时候使用列表;在你提前知道元素数量的情况下使用元组,因为元素的位置很重要。

举个例子,假设你有一个函数是用来在目录中查找结尾为 *.py 的文件。函数返回的应该是一个列表,因为你并不知道你会找到多少个文件,而这些文件都有相同的含义:它们仅仅是你找到的另一个文件。另一方面,让我们假设你需要存储五个值来代表气象观测站的位置:id ,城市,国家,纬度,经度。元组就比列表更适用于这种情况。

把这种“文化差异”放到 C 语言来讲,列表像是数组,元组则像是 structs 结构体。

{lz:python函数参数如果传递的是元组,则为值传递;如果传递的是列表,则为地址传递。这个同c++一样!}[python函数 - 函数的创建及函数参数]

在参数数组中,位置很重要,因为他们是位置参数。但是在函数中,它会接收参数数组并传入另一个函数,它仅仅是一组参数,与其他参数并无不同。其中一些会在调用中变化。Python 之所以在这里使用元组是因为元组比列表更节省空间。列表被重复分配使得在添加元素上更快。这体现了 Python 的实用性:相比于在参数数组上,列表/元组的语义差别,在这种情况下,使用这种数据结构更好。

大部分情况下,你应该根据文化差异来选择使用列表还是元组。思考下你数据的含义。如果实际上根据你的程序来计算,你的数据长度并不固定,那么可能用列表更好。如果在写代码时你知道第三个元素的含义,那么用元组更好。另一方面,函数式编程强调使用不可变的数据结构来避免产生使代码变得更难解读的副作用。如果你喜欢使用函数式编程,那么你可能因为元组的不可变而更喜欢它们。

[Python 列表和元组的区别是什么?]

[送分题:列表与元组的区别是? ]

皮皮Blog

python字典dict

字典除了一般的映射使用,还可以从用于稀疏数据结构角度看:
例如多维数组中只有少数位置上有存储的值
>>> M={}
>>> M[(2,3,4)]=88
>>> M[(7,8,9)]=99  
{(2, 3, 4): 88, (7, 8, 9): 99}
键是元组,他们记录非空元素的坐标。我们并不是分配一个庞大而几乎为空的三维矩阵,而是使用一个简单的两个元素的字典。通过这一方式读取空元素的时,会触发键不存在的异常。因为这些元素实质上并没有被存储。

python字典构建和初始化

键和值的限制

Python调用内部的哈希函数,将键作为参数进行转换,得到一个唯一的地址(这也就解释了为什么给相同的键赋值会直接覆盖的原因,因为相同的键转换后的地址是一样滴),然后将值存放到该地址中。

1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住。哈希算法对相同的值计算结果一样,也就是说1和1.0经过哈希函数得到相同的地址,也就认为这两个键相同。即1和1.0也是相同的键!

2)字典值可以没有限制地取任何python对象,既可以是标准的对象,也可以是用户定义的。

另外,key是不能修改的,主要是内部结构是有序的,改了就破坏了树结构。所以如果想要修改key,就要先删除再插入。(或者直接重载一下dict的赋值运算?)

zip构建

dict(zip(names, range(len(names))))

列表转换成字典

fs_dict = dict.fromkeys(fs_list, True)

Note: dict.fromkeys函数返回的是一个新的dict,而不是改变原dict。所以dict1.fromkeys((1, 2, 3), 'new')是没有效果的。

元组列表转换成字典

dict(seq):创建一个字典,seq必须是一个序列(key,value)元组。

>>> list1 = [(1,2),(2,3)]

>>> dict(list1)

{1: 2, 2: 3}

python dict字典的key必须是hashable的:key不能是list, set(否则出错TypeError: unhashable type: 'list'), 但可以是tuple

{(1, 2): '5', (3, 2): '5'}

python dict字典的key应该会自动转换成同一类型(所有key类型的最小类型?),所以前面的1会被后面的1.0覆盖,而后面的浮点类型1.0会自动转换成int类型1。

In[4]: d = {1:2, 1.0:3}
In[5]: d[1]
3
In[6]: len(d)
1
In[7]: d.keys()
dict_keys([1])

d = {1.0:3}
In[9]: d.keys()
dict_keys([1.0])

python字典初始化

python字典设置value初始类型,指定字典的value类型。

dict字典元素类型初始化设置

music_tag = dict()
for music_name in music_names:music_tag.setdefault(music_name, [])for filename in filenames:if music_name in [line.strip() for line in open(join(DIR, filename))]:music_tag[music_name] += filename.split('.')[0]

dict.setdefault(key, default=None) get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
defaultdict的代码效率高于下面的等效代码:
>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)

defaultdict字典初始化

[python模块 - collections模块: defaultdict]

python dict字典for循环输出

dict1 = {1: 1, 2: 1, 3: 1}
for i in dict1: #等价于dic1.keys()

字典中添加和删除元素

dict.add()返回None

dict删除元素或者整个字典

del dict2['name'] # 删除键为“name”的条目

dict2.clear() # 删除dict2 中所有的条目

del dict2 # 删除整个dict2 字典

dict2.pop('name') # 删除并返回键为“name”的条目

字典解构**

params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 2, 'learning_rate': 0.01, 'loss': 'ls'}
clf = ensemble.GradientBoostingRegressor(**params)

python字典判断是否为空

空的dict直接通过if判断

if dict1: 非空

python 字典查找

1. 通过value 找出key

任何时刻dict.keys()和dict.values()的顺序都是对应的。
try:
    return dict.keys()[dict.values().index(value)]         #python3中要修改为list(dict.keys())[list(dict.values()).index(value)]
except ValueError:
    pass

Note:往dict中添加元素,keys和values加入后都是无序的!但是加入之后相对位置不变。

2. 从字典中获取元素

data = {'user': 1, 'name': 'Max', 'three': 4}

方法1:dict.get(key, default=None)

返回指定键的值,如果值不在字典中返回default值

is_admin = data.get('admin', False)

方法2:

try:

is_admin = data['admin']

except KeyError:

is_admin = False

python中两个字典的操作

python两个字典合并操作

dict1 = {1:1, 2:1, 3:1}
dict2 = {3:2, 4:2, 5:2}
dict1.update(dict2)
print(dict1)

Note: dict key相同的value以更新值为主,也就是dict2。

Adding two dictionaries两个字典相加(合并)

x = {'a':1, 'b': 2}

y = {'b':10, 'c': 11, 'a':3, 'd':7}
方式1

for k, v in y.items():if k in x:x[k] += velse:x[k] = v

方式2

from collections import Counterz = Counter(x) + Counter(y)

方式3

z = {a: x.get(a, 0) + y.get(a, 0) for a in set(x) | set(y)}

print z

>>>{'a': 4, 'c': 11, 'b': 12, 'd': 7}
Note: 方式1最快,其次方式3。所以简单的程序还是自己手写比较好。

两个字典相减

pos = dict.fromkeys(random.randint(0, 1000000, size=1000000), True)
gt1 = dict.fromkeys(random.randint(0, 1000000, size=1000000), True)
方式1
r = {k: v for k, v in pos.items() if k not in gt1}
方式2
from collections import Counter
r = Counter(pos) - Counter(gt1)

Note: 方式1更快。

python字典排序

对字典按键/按值排序,用元组列表的形式返回,同时使用lambda函数来进行;

sorted(iterable[, cmp[, key[, reverse]]]
cmp和key一般使用lambda

对字典按键key排序,用元组列表的形式返回

1. 使用lambda函数

d = {3:5, 6:3, 2:4}
ds = sorted(d.items(), key=lambda item:item[0], reverse=True) #d[0]表示字典的键
print(ds)
[(6, 3), (3, 5), (2, 4)]

2.采用operator模块的itemgetter函数

from operator import itemgetter
sorted(d, key=itemgetter(1))

[python - 常用函数和全局变量:sorted内置函数]

对字典按值value排序,用元组列表的形式返回

ds = sorted(ds.items(), key=lambda item:item[1], reverse=True)
print(ds)
[(3, 5), (2, 4), (6, 3)]
print(dict(ds))    #又变成无序的了

{2: 4, 3: 5, 6: 3}

分解代码:d.items() 得到[(键,值)]的列表。然后用sorted方法,通过key这个参数,指定排序是按照value,也就是第一个元素d[1]的值来排序。reverse = True表示是需要翻转的,默认是从小到大,翻转的话,那就是从大到小。

collections.OrderedDict有序字典

[collections模块- OrderedDict]

Dictionary Comprehensions字典解析

One use for generators can be to build a dictionary, like in the first example below. This proved itself to be common enough that now there is even a newdictionary comprehension syntax for it. Both of these examples swap the keys and values of the dictionary.

 

teachers = {

'Andy': 'English',

'Joan': 'Maths',

'Alice': 'Computer Science',

}

# using a list comprehension

subjects = dict((subject, teacher) for teacher, subject in teachers.items())

# using a dictionary comprehension

subjects = {subject: teacher for teacher, subject in teachers.items()}

>>> m = {x: 'A' + str(x) for x in range(10)}

{0: 'A0', 1: 'A1', 2: 'A2', 3: 'A3', 4: 'A4', 5: 'A5', 6: 'A6', 7: 'A7', 8: 'A8', 9: 'A9'}

Note: 字典解析中的if判断是对value来说的,如:

loc2type_dict = {vid: vcat.split(',') if not pd.isnull(vcat) else ['notype'] for _, (vid, vcat) in df.iterrows()}

Inverting a dictionary using a dictionary comprehension翻转字典中的key和value

>>> m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> m
{'d': 4, 'a': 1, 'b': 2, 'c': 3}
>>> {v: k for k, v in m.items()}
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}

Note: 也可以使用zip反相字典对象

皮皮Blog

python dict和set都是使用hash表来实现(类似C++11标准库中unordered_map),查找元素的时间复杂度是O(1)。dict和set的查找性能差不多(如在list中in查找时)。

python集合操作

集合是无序的!

集合加入、删除元素

add(elem)(已存在就不加入)

Add element elem to the set.

remove(elem)

Remove element elem from the set. Raises KeyError if elem isnot contained in the set.

discard(elem)

Remove element elem from the set if it is present.

pop()

Remove and return an arbitrary element from the set. RaisesKeyError if the set is empty.

clear()

Remove all elements from the set.

将整个新集合加入到本集合中

update(*others)¶

集合间操作

>>> a = set('abracadabra')

>>> b = set('alacazam')
>>> a                                  # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b                              # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b                              # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b                              # letters in both a and b
set(['a', 'c'])
>>> a ^ b                              # letters in a or b but not both

set(['r', 'd', 'b', 'm', 'z', 'l'])

判断子集、父集

issuperset(other)¶

s = {1, 2, 3, 4}
a = (1, 2)
if s.issuperset([*a]):print('***')

issubset(other)¶

[class set([iterable])¶]

[Multisets and multiset operations (collections.Counter) ]

皮皮Blog

python基本类型特殊操作

python 遍历一个dict、set类型的同时,并且在改变这个变量的长度或者一边遍历一边修改,这时候就会抛出这错误:

RuntimeError: dictionary changed size during iteration   # 字典在迭代的时候改变了字典大小

示例:

d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}

for i in d:
    if not d[i]:
        d.pop(i)

原因:用for in 迭代的时候是用迭代器的,不能在迭代的时候添加或删除属性,只能更改属性值。

解决:

# python2中遍历 dictVar.keys(),返回一个列表,从而得到一个列表,这样可以一边遍历列表一遍修改字典;

# 但是这个方法在python3中无法使用,因为这时候按照遍历 dictVar.keys(),返回一个迭代器而不再是一个列表,所以这个时候把字典作为参数放到list方法内,这样才能返回一个列表;

In Python 2.x calling keys makes a copy of the key that you can iterate over while modifying the dict:

for i in d.keys():
Note that this doesn't work in Python 3.x because keys returns an iterator instead of a list.
Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:

for i in list(d):

同理set也是​一样: for i in list(some_set):...

数据类型转换

基本数据类型转换

[python函数: 内置函数 ]

列表,元组和字符串之间的互相转换

python中三个内建函数:str(),tuple()和list()

str<=>list | tuple

标准python类型转换成的字符串 转成 python类型都可以使用

方法 from ast import literal_eval

literal_eval(str(l))

[ast — Abstract Syntax Trees]

Note: 直接使用eval会有安全问题,会被植入代码攻击。

字符串转换为list、tuple

>>> s = "xxxxx"
>>> list(s)
['x', 'x', 'x', 'x', 'x']
>>> tuple(s)
('x', 'x', 'x', 'x', 'x')
>>> tuple(list(s))
('x', 'x', 'x', 'x', 'x')
>>> list(tuple(s))
['x', 'x', 'x', 'x', 'x']

list格式的string转成list,如l = ['1', '2'],转str(l)="['1', '2']"为l。

方法1:from ast import literal_eval

literal_eval(str(l))

方法2:

[i.strip().strip(r'\'') for i in re.split(r',', str(l).strip('[|]')) if l is not np.nan]

列表和元组转换为字符串则必须依靠join函数

>>> "".join(tuple(s))
'xxxxx'
>>> "".join(list(s))
'xxxxx'
>>> str(tuple(s))
"('x', 'x', 'x', 'x', 'x')"

当然如果x中的元素不是字符串可以先转换一下

' '.join([str(i) for i in x]) 或者 ' '.join(np.array(x).astype(str))

dict<=>list | tuple

列表|元组|字符串 转 字典

1 rankDict = dict(rank)

tuple列表转字典(word2id或者id2word的vocabulary构建实现)

dict( zip(*tuple_list) )

或者vocab = dict([(x, y) for (y, x) in enumerate(reverse_vocab)])

2 元组列表转换成字典

[('9', '7'), ('8', '5'), ('8', '4'), ('9', '3'), ('7', '3'), ('7', '2')]
{i:j for i, j in bc_s}

如果有像上面重复的keys:

bc_ss = defaultdict(list)
for bc in bc_s:bc_ss[bc[0]].append(bc[1])

两个列表转换成字典:

post_data = dict(zip(["retcode", "servertime", "pcid", "nonce", "pubkey", "rsakv", "exectime"], post_ori_data))

3 字符串转字典

dict = eval("{'a': 23, 'b': 2}")

或者 先将dict转换成str,保存,再loads str就变成dict。

a = json.dumps(dict0) dict0 = json.loads(a)

或者 直接读取str,但是str中的字符串需要是""不能是''包括着(Expecting property name enclosed in double quotes),所以不能使用str(dict0)来将dict转成str,而需要使用json.dumps()。

json.loads('''{"a": 23, "b": 2}''')

4  列表|元组|字符串直接转dict

dict.fromkeys(S)

S是一个列表或元组...,将S中的元素作为字典的key,value默认为None,也可以指定一个初始值,代码示例:

myDict = dict.fromkeys('hello', True)
for k in myDict.keys():print(k, myDict[k])
h True
e True
l True
o True

字典 转 元组|列表

字典转tuple列表

a = {1:23,8:43,3:34,9:28}
print(list(a.items()))

print(list(zip(a.keys(),a.values())))

转换成可迭代对象

使用iter() 函数用来生成迭代器。

有下列字符串:

user = "{'name' : 'jim', 'sex' : 'male', 'age': 18}"

字典dict转类对象

d = {"d1":111, "d2":222}

x = type('new_dict', (object,), d)

这样就可以通过x.d1得到111这个值了。

嵌套字典dict转类对象:添加递归到这个

def obj_dic(d):
    top = type('new', (object,), d)
    seqs = tuple, list, set, frozenset
    for i, j in d.items():
        if isinstance(j, dict):
            setattr(top, i, obj_dic(j))
        elif isinstance(j, seqs):
            setattr(top, i, 
                type(j)(obj_dic(sj) if isinstance(sj, dict) else sj for sj in j))
        else:
            setattr(top, i, j)
    return top

[将嵌套的Python dict转换为对象?]

如何将字符串转化成字典dict类型

参考字典初始化

from:http://blog.csdn.net/pipisorry/article/details/39234557

ref:30 Python Language Features and Tricks You May Not Know About

Hidden features of Python [closed]

Python: Tips, Tricks and Idioms

Python程序的执行原理

python入门:基础,列表、元组、字典及集合类型相关推荐

  1. day02 格式化输出 运算符 编码 字符串 列表 元组 字典 set集合 深浅拷贝

    day02学习大纲 一. 格式化输出: %s 占位字符串 %d 占位数字 "xxx%sx %sxx" % (变量, 变量) 二. 运算符: a+=b a = a + b and 并 ...

  2. python变量 数据类型 列表 元组 字典

    python基础语法2 变量 数据类型与类型转换 列表 添加列表元素 修改元素 删除列表元素 组织列表 创建数值列表 操作列表 元组 元组转列表 字典 创建字典 列表取值 字典删除增加修改 变量 变量 ...

  3. python入门之 列表 元组 集合 字典 最全教程

    一.列表 列表(list)是Python中的一种数据结构,它可以存储不同类型的数据.不同元素以逗号分隔. //下标索引访问 A = ['xiaoWang', 'xiaoZhang', 'xiaoHua ...

  4. mysql cbrt函数_基础方法或属性: 列表,元组,字典,字符串,集合及内置函数等(注:只有英文名)...

    列表 list append clear copy count extend index insert pop remove reverse sort 元组 tuple count index 字典 ...

  5. *python高级数据-列表-元组-字典

    列表list 列表用来存放多条数据:字符串.int.list.dict等都可以 储存一系列名字,存储一些新闻条目,可以使用列表的格式. # 例如 Name = '张三' Name2 = 'lisi' ...

  6. 儿童python教程书-Python入门基础教程(儿童版) [分享一本入门级教程]

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1. 推荐书名 No Starch--Python for ...

  7. python.集合转列表_Python基础数据类型:元组、列表、字典、集合

    你好,我是goldsunC. 让我们一起进步吧! 元组.列表.字典.集合 元组和列表是Python语言中非常重要的一部分内容,它们是Python中除了字符串以外的另两种序列结构,几乎在任何地方都少不了 ...

  8. Python 字符串/列表/元组/字典之间的相互转换 - Python零基础入门教程

    目录 一.字符串 str 与列表 list 1.字符串转列表 2.列表转字符串 二.字符串 str 与字典 dict 1.字符串转字典 2.字典转字符串 三.列表 list 与字典 dict 1.列表 ...

  9. python列表添加元素的三种方法定义集合数据对象_(1) List,tuple,dictionary,Python语法基础集,一,之,列表,元组,字典,集合...

    Python序列(列表.元组.字典.集合) 一.列表(List)与列表推导式 (一)列表(list) 1.列表是Python内置 可变序列 (列表中元素可增加删除或修改): 2.列表元素放在一对中括号 ...

  10. 【Python基础】使用列表、字典和集合生成式来缩短代码

    作者 | Philip Wilkinson 编译 | VK 来源 | Towards Datas Science 在使用Python将近一年的时间里,我经常遇到"生成式"这个词,但 ...

最新文章

  1. java第六章工具包P6-03.Optional 2020.4.?
  2. java中怎么表示数组中的某个值_简易Java(12):如何高效检查一个数组中是否包含某个值?...
  3. 【C#桌面应用】第二节:利用Visual Studio2019 创建桌面应用
  4. SWOT分析法(态势分析法)
  5. MATLAB使用及介绍
  6. web前端emoji表情
  7. if while的用法
  8. SQL Server 2008 误删除数据的恢复
  9. 抖音康辉机器人_新闻联播主持康辉玩抖音,卖萌耍宝样样精通,观众为其点赞...
  10. 08-OS X系统中将control和command键互换
  11. 和开源硬件相关的几个词,免费、山寨、创客教育,以及未来 | COSCon'18
  12. 电力系统数字化转型历史(跨部门系统自建阶段)
  13. SQL——DDBC手册
  14. 基于web的家庭理财系统
  15. IIR滤波器和FIR滤波器的区别与联系
  16. html bs架构调用客户端打印机用客户端及客户端局域网打印机打印,使用ScriptX.cab控件...
  17. 2021游戏安全行业峰会:安全共建,护航产业健康发展
  18. 基于RT-Thread系统的机智云数字仪表教程(一)——移植RT-Thread的BSP模板
  19. Ubuntu双网卡共享上网 外网 内网
  20. 项目中的软件质量管理

热门文章

  1. cdoj 邱老师看电影
  2. .net Entity Framework初识1
  3. VSCode 写python,打印中文输出乱码
  4. gcc与g++编译器介绍
  5. 微软于 snapcraft 上发布 Visual Studio Code 的 Snap 打包版本
  6. 个人永久性免费-Excel催化剂功能第31波-数量金额分组凑数功能,财务表哥表姐最爱...
  7. Vs2010中水晶报表引用及打包
  8. 乱七八糟 Nodejs 系列一:试水
  9. 对数字信号处理中各种频率以及分辨率的理解
  10. BERT中CLS效果真的好嘛?这篇文章告诉你答案