萌新向Python数据分析及数据挖掘 第二章 pandas 第三节 Built-in Data Structures, Functions, Data Structures and Sequences
Built-in Data Structures, Functions,
Data Structures and Sequences
### 元组
tup = 4, 5, 6
tup
nested_tup = (4, 5, 6), (7, 8)
nested_tup
tuple([4, 0, 2])
tup = tuple('string')
tup
Init signature: tuple(self, /, *args, **kwargs)
Docstring:
tuple() -> empty tuple
tuple(iterable) -> tuple initialized from iterable's items
If the argument is a tuple, the return value is the same object.
Type: type
tup[0]
tup = tuple(['foo', [1, 2], True])
tup[2] = False
tup[1].append(3)
tup
(4, None, 'foo') + (6, 0) + ('bar',)
('foo', 'bar') * 4
Unpacking tuples
tup = (4, 5, 6)
a, b, c = tup
b
tup = 4, 5, (6, 7)
a, b, (c, d) = tup
d
tmp = a a = b b = tmp
a, b = 1, 2
a
b
b, a = a, b
a
b
seq = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
for a, b, c in seq:
print('a={0}, b={1}, c={2}'.format(a, b, c))
values = 1, 2, 3, 4, 5
a, b, *rest = values
a, b
rest
a, b, *_ = values
Tuple methods
a = (1, 2, 2, 2, 3, 4, 2)
a.count(2)
List
a_list = [2, 3, 7, None]
tup = ('foo', 'bar', 'baz')
b_list = list(tup)
b_list
b_list[1] = 'peekaboo'
b_list
gen = range(10)
gen
list(gen)
Adding and removing elements
b_list.append('dwarf')
b_list
Docstring: L.append(object) -> None -- append object to end
Type: builtin_function_or_method
b_list.insert(1, 'red')
b_list
Docstring: L.insert(index, object) -- insert object before index
Type: builtin_function_or_method
b_list.pop(2)
b_list
Docstring:
L.pop([index]) -> item -- remove and return item at index (default last).
Raises IndexError if list is empty or index is out of range.
Type: builtin_function_or_method
b_list.append('foo')
b_list
b_list.remove('foo')
b_list
Docstring:
L.remove(value) -> None -- remove first occurrence of value.
Raises ValueError if the value is not present.
Type: builtin_function_or_method
'dwarf' in b_list
'dwarf' not in b_list
Concatenating and combining lists
[4, None, 'foo'] + [7, 8, (2, 3)]
x = [4, None, 'foo']
x.extend([7, 8, (2, 3)])
x
Docstring: L.extend(iterable) -> None -- extend list by appending elements from the iterable
Type: builtin_function_or_method
everything = [] for chunk in list_of_lists: everything.extend(chunk)
everything = [] for chunk in list_of_lists: everything = everything + chunk
Sorting
a = [7, 2, 5, 1, 3]
a.sort()
a
Docstring: L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
Type: builtin_function_or_method
b = ['saw', 'small', 'He', 'foxes', 'six']
b.sort(key=len)
b
Binary search and maintaining a sorted list
import bisect ###输出一个元素在已排序的列表中的序号,而不改变列表
c = [1, 2, 2, 2, 3, 4, 7]
bisect.bisect(c, 2)
Docstring: Alias for bisect_right().
Type: builtin_function_or_method
bisect.bisect(c, 5)
bisect.insort(c, 6)
c
Slicing
seq = [7, 2, 3, 7, 5, 6, 0, 1]
seq[1:5]
seq[3:4] = [6, 3]
seq
seq[:5]
seq[3:]
seq[-4:]
seq[-6:-2]
seq[::2]
seq[::-1]
Built-in Sequence Functions
enumerate
i = 0 for value in collection:
do something with value
i += 1
for i, value in enumerate(collection):
do something with value
some_list = ['foo', 'bar', 'baz']
mapping = {}
for i, v in enumerate(some_list):
mapping[v] = i
mapping
Init signature: enumerate(self, /, *args, **kwargs)
Docstring:
enumerate(iterable[, start]) -> iterator for index, value of iterable
Return an enumerate object. iterable must be another object that supports
iteration. The enumerate object yields pairs containing a count (from
start, which defaults to zero) and a value yielded by the iterable argument.
enumerate is useful for obtaining an indexed list:
(0, seq[0]), (1, seq[1]), (2, seq[2]), ...
Type: type
sorted
sorted([7, 1, 2, 6, 0, 3, 2])
sorted('horse race')
Signature: sorted(iterable, /, *, key=None, reverse=False)
Docstring:
Return a new list containing all items from the iterable in ascending order.
A custom key function can be supplied to customize the sort order, and the
reverse flag can be set to request the result in descending order.
Type: builtin_function_or_method
zip
seq1 = ['foo', 'bar', 'baz']
seq2 = ['one', 'two', 'three']
zipped = zip(seq1, seq2)
list(zipped)
seq3 = [False, True]
list(zip(seq1, seq2, seq3))###转置大法
for i, (a, b) in enumerate(zip(seq1, seq2)):
print('{0}: {1}, {2}'.format(i, a, b))
pitchers = [('Nolan', 'Ryan'), ('Roger', 'Clemens'),
('Schilling', 'Curt')]
first_names, last_names = zip(*pitchers#反向zip
first_names
last_names
reversed
list(reversed(range(10)))
Init signature: reversed(self, /, *args, **kwargs)
Docstring:
reversed(sequence) -> reverse iterator over values of the sequence
Return a reverse iterator
Type: type
dict
empty_dict = {}
d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}
d1
d1[7] = 'an integer'
d1
d1['b']
'b' in d1
d1[5] = 'some value'
d1
d1['dummy'] = 'another value'
d1
del d1[5]
d1
ret = d1.pop('dummy')
ret
d1
list(d1.keys())
list(d1.values())
d1.update({'b' : 'foo', 'c' : 12})
d1
Creating dicts from sequences
mapping = {} for key, value in zip(key_list, value_list): mapping[key] = value
mapping = dict(zip(range(5), reversed(range(5))))
mapping
Init signature: zip(self, /, args, *kwargs) Docstring:
zip(iter1 [,iter2 [...]]) --> zip object
Return a zip object whose .next() method returns a tuple where the i-th element comes from the i-th iterable argument. The .next() method continues until the shortest iterable in the argument sequence is exhausted and then it raises StopIteration. Type: type
Default values
if key in some_dict: value = some_dict[key] else: value = default_value
value = some_dict.get(key, default_value)
words = ['apple', 'bat', 'bar', 'atom', 'book']
by_letter = {}
for word in words:
letter = word[0]
if letter not in by_letter:
by_letter[letter] = [word]
else:
by_letter[letter].append(word)
by_letter
for word in words: letter = word[0] by_letter.setdefault(letter, []).append(word)
from collections import defaultdict by_letter = defaultdict(list) for word in words: by_letter[word[0]].append(word)
Valid dict key types
hash('string')
hash((1, 2, (2, 3)))
hash((1, 2, [2, 3])) # fails because lists are mutable
d = {}
d[tuple([1, 2, 3])] = 5#元组作为key
d
set
set([2, 2, 2, 1, 3, 3])
{2, 2, 2, 1, 3, 3}
a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7, 8}
a.union(b)#并集
a | b
a.intersection(b)#交集
a & b
c = a.copy()
c |= b
c
d = a.copy()
d &= b
d
my_data = [1, 2, 3, 4]
my_set = {tuple(my_data)}
my_set
a_set = {1, 2, 3, 4, 5}
{1, 2, 3}.issubset(a_set)
a_set.issuperset({1, 2, 3})
{1, 2, 3} == {3, 2, 1}#无排序
### List, Set, and Dict Comprehensions
[
result = [] for val in collection: if
strings = ['a', 'as', 'bat', 'car', 'dove', 'python']
[x.upper() for x in strings if len(x) > 2]
dict_comp = {
set_comp = {
unique_lengths = {len(x) for x in strings}
unique_lengths
set(map(len, strings))
loc_mapping = {val : index for index, val in enumerate(strings)}
loc_mapping
Nested list comprehensions
all_data = [['John', 'Emily', 'Michael', 'Mary', 'Steven'],
['Maria', 'Juan', 'Javier', 'Natalia', 'Pilar']]
names_of_interest = [] for names in all_data: enough_es = [name for name in names if name.count('e') >= 2] names_of_interest.extend(enough_es)
result = [name for names in all_data for name in names #列表筛选
if name.count('e') >= 2]
result
some_tuples = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
flattened = [x for tup in some_tuples for x in tup]
flattened
flattened = []
for tup in some_tuples: for x in tup: flattened.append(x)
[[x for x in tup] for tup in some_tuples]
Functions
def my_function(x, y, z=1.5): if z > 1: return z * (x + y) else: return z / (x + y)
my_function(5, 6, z=0.7) my_function(3.14, 7, 3.5) my_function(10, 20)
Namespaces, Scope, and Local Functions
def func(): a = [] for i in range(5): a.append(i)
a = [] def func(): for i in range(5): a.append(i)
a = None
def bind_a_variable():
global a
a = []
bind_a_variable()
print(a)
Returning Multiple Values
def f(): a = 5 b = 6 c = 7 return a, b, c
a, b, c = f()
return_value = f()
def f(): a = 5 b = 6 c = 7 return {'a' : a, 'b' : b, 'c' : c}
Functions Are Objects
states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda',
'south carolina##', 'West virginia?']
import re #正则匹配
def clean_strings(strings):
result = []
for value in strings:
value = value.strip()#去空格
value = re.sub('[!#?]', '', value)#去特殊符号
value = value.title()#首字母大写
result.append(value)
return result
clean_strings(states)
def remove_punctuation(value):
return re.sub('[!#?]', '', value)
clean_ops = [str.strip, remove_punctuation, str.title]
def clean_strings(strings, ops):
result = []
for value in strings:
for function in ops:
value = function(value)
result.append(value)
return result
clean_strings(states, clean_ops)
for x in map(remove_punctuation, states):
print(x)
Anonymous (Lambda) Functions
def short_function(x): return x * 2
equiv_anon = lambda x: x * 2
def apply_to_list(some_list, f): return [f(x) for x in some_list]
ints = [4, 0, 1, 5, 6] apply_to_list(ints, lambda x: x * 2)
strings = ['foo', 'card', 'bar', 'aaaa', 'abab']
strings.sort(key=lambda x: len(set(list(x))))#按字符串所含不同字母个数排序
strings
Currying: Partial Argument Application
def add_numbers(x, y): return x + y
add_five = lambda y: add_numbers(5, y)
from functools import partial add_five = partial(add_numbers, 5)
Generators
some_dict = {'a': 1, 'b': 2, 'c': 3}
for key in some_dict:
print(key)
dict_iterator = iter(some_dict)
dict_iterator
list(dict_iterator)
def squares(n=10):
print('Generating squares from 1 to {0}'.format(n ** 2))
for i in range(1, n + 1):
yield i ** 2
gen = squares()
gen
for x in gen:
print(x, end=' ')
Generator expresssions
gen = (x ** 2 for x in range(100))
gen
def makegen(): for x in range(100): yield x ** 2 gen = makegen()
sum(x ** 2 for x in range(100))
dict((i, i **2) for i in range(5))
itertools module
import itertools
first_letter = lambda x: x[0]
names = ['Alan', 'Adam', 'Wes', 'Will', 'Albert', 'Steven']
for letter, names in itertools.groupby(names, first_letter):
print(letter, list(names)) # names is a generator
Init signature: itertools.groupby(self, /, *args, **kwargs)
Docstring:
groupby(iterable, key=None) -> make an iterator that returns consecutive
keys and groups from the iterable. If the key function is not specified or
is None, the element itself is used for grouping.
Type: type
Errors and Exception Handling
float('1.2345')
float('something')
def attempt_float(x):
try:
return float(x)
except:
return x
attempt_float('1.2345')
attempt_float('something')
float((1, 2))
def attempt_float(x):
try:
return float(x)
except ValueError:
return x
attempt_float((1, 2))
def attempt_float(x):
try:
return float(x)
except (TypeError, ValueError):
return x
f = open(path, 'w')
try: write_to_file(f) finally: f.close()
f = open(path, 'w')
try: write_to_file(f) except: print('Failed') else: print('Succeeded') finally: f.close()
Exceptions in IPython
In [10]: %run examples/ipython_bug.py
AssertionError Traceback (most recent call last) /home/wesm/code/pydata-book/examples/ipython_bug.py in () 13 throws_an_exception() 14 ---> 15 calling_things()
/home/wesm/code/pydata-book/examples/ipython_bug.py in calling_things() 11 def calling_things(): 12 works_fine() ---> 13 throws_an_exception() 14 15 calling_things()
/home/wesm/code/pydata-book/examples/ipython_bug.py in throws_an_exception() 7 a = 5 8 b = 6 ----> 9 assert(a + b == 10) 10 11 def calling_things():
AssertionError:
Files and the Operating System
%pushd book-materials
path = 'examples/segismundo.txt'
f = open(path)
for line in f: pass
lines = [x.rstrip() for x in open(path)]
lines
f.close()
with open(path) as f:
lines = [x.rstrip() for x in f]
f = open(path)
f.read(10)
f2 = open(path, 'rb') # Binary mode
f2.read(10)
f.tell()
f2.tell()
import sys
sys.getdefaultencoding()#获得默认编码
f.seek(3)
f.read(1)
f.close()
f2.close()
with open('tmp.txt', 'w') as handle:
handle.writelines(x for x in open(path) if len(x) > 1)
with open('tmp.txt') as f:
lines = f.readlines()
lines
import os
os.remove('tmp.txt')
Bytes and Unicode with Files
with open(path) as f:
chars = f.read(10)
chars
with open(path, 'rb') as f:
data = f.read(10)
data
data.decode('utf8')
data[:4].decode('utf8')
sink_path = 'sink.txt'
with open(path) as source:
with open(sink_path, 'xt', encoding='iso-8859-1') as sink:
sink.write(source.read())
with open(sink_path, encoding='iso-8859-1') as f:
print(f.read(10))
os.remove(sink_path)
f = open(path)
f.read(5)
f.seek(4)
f.read(1)
f.close()
%popd