Python資料結構與演算法相關問題與解決技巧
阿新 • • 發佈:2018-12-05
1.如何在列表, 字典, 集合中根據條件篩選資料
from random import randint
data = [randint(-10,10) for _ in range(10)]
data
[4, 4, -5, 6, 7, 10, 5, -7, -6, -9]
# 篩選出列表中大於0的元素
# 使用filter函式
list(filter(lambda x:x>=0,data))
[4, 4, 6, 7, 10, 5]
# 列表解析
[x for x in data if x >= 0]
[4, 4, 6, 7, 10, 5]
timeit list(filter(lambda x:x>=0,data))
1.56 µs ± 33.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
timeit [x for x in data if x >= 0]
625 ns ± 26.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
# 字典解析
d = {x:randint(60,100) for x in range(1,21)}
d
{1: 87, 2: 86, 3: 97, 4: 92, 5: 79, 6: 90, 7: 78, 8: 97, 9: 63, 10: 97, 11: 91, 12: 69, 13: 86, 14: 83, 15: 84, 16: 83, 17: 70, 18: 86, 19: 93, 20: 88}
{k:v for k,v in d.items() if v > 90 }
{3: 97, 4: 92, 8: 97, 10: 97, 11: 91, 19: 93}
# 集合解析
s = set(data)
s
{-9, -7, -6, -5, 4, 5, 6, 7, 10}
{x for x in s if x % 2 == 0}
{-6, 4, 6, 10}
2.如何為元組中的每個元素命名, 提高程式可讀性
#方案一,定義一系列數值常量
NAME,AGE,SEX,EMAIL = range(4)
student = ('Tom','16','male','[email protected] ')
student[NAME]
'Tom'
#方案二,使用namedtuple
from collections import namedtuple
Student = namedtuple('Student',['name','age','sex','email'])
#位置傳參
s = Student('Tom','16','male','[email protected]')
s
Student(name='Tom', age='16', sex='male', email='[email protected]')
#關鍵字傳參
s2 = Student(name='Tom',age='16',sex='male',email='[email protected]')
s2
Student(name='Tom', age='16', sex='male', email='[email protected]')
s.name
'Tom'
s.email
'[email protected]'
isinstance(s,tuple)
True
3.如何統計序列中元素的出現頻度
from random import randint
data = [randint(0,20) for _ in range(30)]
data
[8,
11,
16,
10,
11,
10,
13,
6,
20,
15,
19,
13,
4,
14,
8,
18,
9,
8,
9,
19,
11,
15,
9,
4,
2,
11,
11,
16,
3,
19]
#fromkeys:用於建立並返回一個新的字典。兩個引數:第一個是字典的鍵,第二個(可選)是傳入鍵的值,預設為None。
c = dict.fromkeys(data,0)
c
{8: 0,
11: 0,
16: 0,
10: 0,
13: 0,
6: 0,
20: 0,
15: 0,
19: 0,
4: 0,
14: 0,
18: 0,
9: 0,
2: 0,
3: 0}
for x in data:
c[x] += 1
c
{8: 3,
11: 5,
16: 2,
10: 2,
13: 2,
6: 1,
20: 1,
15: 2,
19: 3,
4: 2,
14: 1,
18: 1,
9: 3,
2: 1,
3: 1}
# 使用Counter
from collections import Counter
c2 = Counter(data)
c2
Counter({8: 3,
11: 5,
16: 2,
10: 2,
13: 2,
6: 1,
20: 1,
15: 2,
19: 3,
4: 2,
14: 1,
18: 1,
9: 3,
2: 1,
3: 1})
#找出頻率出現最高的3個元素
c2.most_common(3)
[(11, 5), (8, 3), (19, 3)]
import re
txt = open('Alice.txt').read()
c3 = Counter(re.split('\W+',txt))
c3
Counter({'Alice': 19,
'was': 38,
'beginning': 1,
'to': 44,
'get': 5,
'very': 12,
'tired': 1,
'of': 25,
'sitting': 1,
'by': 6,
'her': 15,
'sisteron': 1,
'the': 58,
'bank': 1,
'and': 44,
'having': 1,
'nothing': 5,
'do': 5,
'once': 1,
'or': 9,
'twice': 1,
'she': 45,
'hadpeeped': 1,
'into': 4,
'book': 4,
'sister': 1,
'reading': 1,
'but': 14,
'it': 45,
'had': 12,
'nopictures': 1,
'conversations': 1,
'in': 17,
'what': 6,
'is': 4,
'use': 3,
'a': 36,
'thought': 5,
'without': 2,
'pictures': 2,
'conversation': 1,
'So': 1,
'considering': 1,
'own': 1,
'mind': 2,
'as': 13,
'well': 5,
'could': 5,
'for': 11,
'hot': 3,
'day': 1,
'made': 2,
'feel': 1,
'sleepy': 2,
'stupid': 1,
'whetherthe': 1,
'pleasure': 1,
'making': 1,
'daisy': 1,
'chain': 1,
'would': 5,
'be': 8,
'worth': 1,
'troubleof': 1,
'getting': 3,
'up': 9,
'picking': 1,
'daisies': 1,
'when': 6,
'suddenly': 4,
'WhiteRabbit': 1,
'with': 10,
'pink': 1,
'eyes': 1,
'ran': 2,
'close': 2,
'There': 6,
'so': 8,
'VERY': 4,
'remarkable': 1,
'that': 18,
'nor': 1,
'did': 3,
'Alicethink': 1,
'much': 5,
'out': 8,
'way': 5,
'hear': 2,
'Rabbit': 4,
'say': 4,
'toitself': 1,
'Oh': 4,
'dear': 3,
'I': 21,
'shall': 3,
'late': 1,
'thoughtit': 1,
'over': 3,
'afterwards': 1,
'occurred': 1,
'ought': 1,
'havewondered': 1,
'at': 9,
'this': 8,
'time': 8,
'all': 9,
'seemed': 2,
'quite': 1,
'natural': 1,
'actually': 1,
'TOOK': 1,
'A': 1,
'WATCH': 1,
'OUT': 1,
'OF': 1,
'ITS': 1,
'WAISTCOAT': 1,
'POCKET': 1,
'looked': 3,
'then': 4,
'hurried': 1,
'on': 8,
'started': 1,
'toher': 1,
'feet': 2,
'flashed': 1,
'across': 2,
'neverbefore': 1,
'seen': 2,
'rabbit': 3,
'either': 3,
'waistcoat': 1,
'pocket': 1,
'watch': 1,
'totake': 1,
'burning': 1,
'curiosity': 1,
'thefield': 1,
'after': 3,
'fortunately': 1,
'just': 3,
'see': 7,
'popdown': 1,
'large': 3,
'hole': 3,
'under': 1,
'hedge': 1,
'In': 1,
'another': 3,
'moment': 2,
'down': 16,
'went': 5,
'never': 1,
'onceconsidering': 1,
'how': 6,
'world': 1,
'again': 4,
'The': 2,
'straight': 1,
'like': 5,
'tunnel': 1,
'some': 1,
'dipped': 1,
'not': 13,
'amoment': 2,
'think': 9,
'about': 6,
'stopping': 1,
'herself': 3,
'before': 4,
'found': 3,
'herselffalling': 1,
'deep': 2,
'Either': 1,
'fell': 2,
'slowly': 1,
'shehad': 1,
'plenty': 1,
'look': 1,
'towonder': 1,
'going': 2,
'happen': 1,
'next': 1,
'First': 1,
'tried': 2,
'lookdown': 1,
'make': 1,
'coming': 1,
'too': 4,
'dark': 3,
'tosee': 1,
'anything': 2,
'sides': 1,
'andnoticed': 1,
'they': 6,
'were': 6,
'filled': 1,
'cupboards': 2,
'shelves': 2,
'here': 4,
'there': 4,
'saw': 2,
'maps': 1,
'hung': 1,
'upon': 4,
'pegs': 1,
'Shetook': 1,
'jar': 2,
'from': 3,
'one': 6,
'passed': 1,
'waslabelled': 1,
'ORANGE': 1,
'MARMALADE': 1,
'great': 2,
'disappointment': 1,
'itwas': 1,
'empty': 1,
'drop': 1,
'fear': 1,
'killingsomebody': 1,
'managed': 1,
'put': 2,
'shefell': 1,
'past': 1,
'Well': 1,
'such': 2,
'fall': 4,
'Ishall': 1,
'tumbling': 1,
'stairs': 1,
'How': 3,
'brave': 1,
'llall': 1,
'me': 6,
'home': 1,
'Why': 1,
'wouldn': 1,
't': 4,
'even': 3,
'if': 6,
'off': 4,
'top': 1,
'house': 1,
'Which': 1,
'likelytrue': 1,
'Down': 2,
'Would': 1,
'NEVER': 1,
'come': 2,
'an': 1,
'end': 1,
'Iwonder': 1,
'many': 2,
'miles': 2,
've': 2,
'fallen': 1,
'said': 3,
'aloud': 1,
'must': 1,
'somewhere': 2,
'near': 1,
'centre': 1,
'earth': 2,
'Letme': 1,
'four': 1,
'thousand': 1,
'you': 16,
'learnt': 1,
'several': 2,
'things': 1,
'sort': 2,
'herlessons': 1,
'schoolroom': 1,
'though': 2,
'goodopportunity': 1,
'showing': 1,
'knowledge': 1,
'no': 6,
'tolisten': 1,
'still': 2,
'good': 1,
'practice': 1,
'yes': 1,
's': 5,
'right': 2,
'distance': 1,
'wonder': 3,
'Latitudeor': 1,
'Longitude': 2,
'got': 2,
'idea': 1,
'Latitude': 1,
'nice': 3,
'grand': 1,
'words': 2,
'tosay': 1,
'Presently': 1,
'began': 2,
'rightTHROUGH': 1,
'funny': 1,
'll': 5,
'seem': 1,
'among': 1,
'thepeople': 1,
'walk': 1,
'their': 1,
'heads': 1,
'downward': 1,
'Antipathies': 1,
'Ithink': 1,
'rather': 1,
'glad': 1,
'WAS': 1,
'listening': 1,
'thistime': 1,
'didn': 2,
'sound': 1,
'word': 1,
'shallhave': 1,
'ask': 2,
'them': 2,
'name': 1,
'country': 1,
'know': 2,
'Please': 1,
'Ma': 1,
'am': 1,
'New': 1,
'Zealand': 1,
'Australia': 1,
'triedto': 1,
'curtsey': 1,
'spoke': 1,
'fancy': 1,
'CURTSEYING': 1,
're': 1,
'fallingthrough': 1,
'air': 2,
'Do': 3,
'manage': 1,
'And': 2,
'whatan': 1,
'ignorant': 1,
'little': 7,
'girl': 1,
'asking': 1,
'No': 2,
'llnever': 1,
'perhaps': 1,
'written': 1,
'else': 1,
'soonbegan': 1,
'talking': 1,
'Dinah': 5,
'miss': 1,
'night': 1,
'Ishould': 1,
'cat': 1,
'hope': 1,
'rememberher': 1,
'saucer': 1,
'milk': 1,
'tea': 1,
'my': 3,
'wish': 1,
'weredown': 1,
'are': 1,
'mice': 1,
'm': 1,
'afraid': 1,
'butyou': 1,
'might': 3,
'catch': 1,
'bat': 1,
'mouse': 1,
'But': 1,
'cats': 4,
'eat': 5,
'bats': 3,
'getrather': 1,
'saying': 2,
'dreamy': 1,
'ofway': 1,
'sometimes': 1,
'Dobats': 1,
'couldn': 1,
'answer': 1,
'eitherquestion': 1,
'matter': 1,
'which': 2,
'She': 2,
'feltthat': 1,
'dozing': 1,
'begun': 2,
'dream': 1,
'shewas': 1,
'walking': 1,
'hand': 2,
'veryearnestly': 1,
'Now': 1,
'tell': 1,
'truth': 1,
'ever': 3,
'abat': 1,
'thump': 2,
'came': 3,
'heap': 1,
'ofsticks': 1,
'dry': 1,
'leaves': 1,
'bit': 1,
'hurt': 1,
'jumped': 1,
'overhead': 1,
'herwas': 1,
'long': 3,
'passage': 2,
'White': 1,
'insight': 1,
'hurrying': 1,
'lost': 1,
'away': 1,
'wind': 1,
'itsay': 1,
'turned': 2,
'corner': 1,
'ears': 1,
'whiskers': 1,
'lateit': 1,
'behind': 2,
'thecorner': 1,
'longer': 1,
'foundherself': 1,
'low': 1,
'hall': 4,
'lit': 1,
'row': 1,
'lampshanging': 1,
'roof': 1,
'doors': 1,
'round': 3,
'locked': 1,
'been': 1,
'side': 1,
'theother': 1,
'trying': 1,
'every': 1,
'door': 3,
'walked': 1,
'sadly': 1,
'middle': 1,
'wondering': 1,
'Suddenly': 1,
'three': 1,
'legged': 1,
'table': 2,
'ofsolid': 1,
'glass': 1,
'except': 1,
'tiny': 1,
'golden': 2,
'key': 3,
'first': 1,
'belong': 1,
'thedoors': 1,
'alas': 1,
'locks': 1,
'orthe': 1,
'small': 1,
'any': 3,
'rate': 2,
'open': 1,
'ofthem': 1,
'However': 2,
'second': 1,
'lowcurtain': 1,
'noticed': 1,
'littledoor': 1,
'fifteen': 1,
'inches': 1,
'high': 1,
'keyin': 1,
'lock': 1,
'delight': 1,
'fitted': 1,
'opened': 1,
'led': 1,
'smallpassage': 1,
'larger': 1,
'than': 1,
'rat': 1,
'knelt': 1,
'andlooked': 1,
'along': 1,
'loveliest': 1,
'garden': 1,
'longed': 1,
'wander': 1,
'aboutamong': 1,
'those': 2,
'beds': 1,
'bright': 1,
'flowers': 1,
'cool': 1,
'fountains': 1,
'butshe': 1,
'head': 2,
'doorway': 1,
'ifmy': 1,
'go': 1,
'through': 1,
'poor': 1,
'ofvery': 1,
'shoulders': 1,
'wishI': 1,
'shut': 1,
'telescope': 1,
'onlyknow': 1,
'begin': 1,
'For': 1,
'thingshad': 1,
'happened': 1,
'lately': 1,
'fewthings': 1,
'indeed': 1,
'really': 1,
'impossible': 1,
'waiting': 1,
'shewent': 1,
'back': 1,
'half': 1,
'hoping': 1,
'find': 1,
'onit': 1,
'rules': 1,
'shutting': 1,
'people': 1,
'liketelescopes': 1,
'bottle': 4,
'whichcertainly': 1,
'neckof': 1,
'paper': 1,
'label': 1,
'DRINK': 1,
'ME': 1,
'beautifully': 1,
'printed': 1,
'letters': 1,
'It': 1,
'Drink': 1,
'wise': 1,
'littleAlice': 1,
'THAT': 1,
'hurry': 1,
'lookfirst': 1,
'whether': 1,
'marked': 3,
'poison': 3,
'read': 1,
'histories': 1,
'children': 1,
'whohad': 1,
'burnt': 1,
'eaten': 1,
'wild': 1,
'beasts': 1,
'other': 1,
'unpleasantthings': 1,
'because': 1,
'WOULD': 1,
'remember': 1,
'simple': 1,
'rulestheir': 1,
'friends': 1,
'taught': 1,
'red': 1,
'pokerwill': 1,
'burn': 1,
'hold': 1,
'cut': 1,
'yourfinger': 1,
'deeply': 1,
'knife': 1,
'usually': 1,
'bleeds': 1,
'hadnever': 1,
'forgotten': 1,
'drink': 1,
'almost': 1,
'certain': 1,
'disagree': 1,
'sooner': 1,
'orlater': 1,
'NOT': 1,
'venturedto': 1,
'taste': 1,
'finding': 1,
'fact': 1,
'sortof': 1,
'mixed': 1,
'flavour': 1,
'cherry': 1,
'tart': 1,
'custard': 1,
'pine': 1,
'apple': 1,
'roastturkey': 1,
'toffee': 1,
'buttered': 1,
'toast': 1,
'soon': 1,
'finishedit': 1,
'': 1})
c3.most_common(10)
[('the', 58),
('she', 45),
('it', 45),
('to', 44),
('and', 44),
('was', 38),
('a', 36),
('of', 25),
('I', 21),
('Alice', 19)]
4.如何根據字典中值的大小, 對字典中的項排序
sorted([9,3,1,67,6])
[1, 3, 6, 9, 67]
from random import randint
d = {x:randint(60,100) for x in 'xyzabc'}
d
{'x': 96, 'y': 87, 'z': 86, 'a': 68, 'b': 61, 'c': 75}
d.keys()
dict_keys(['x', 'y', 'z', 'a', 'b', 'c'])
d.values()
dict_values([96, 87, 86, 68, 61, 75])
#方案一:利用zip將字典轉換成元組進行排序
sorted(zip(d.values(),d.keys()))
[(61, 'b'), (68, 'a'), (75, 'c'), (86, 'z'), (87, 'y'), (96, 'x')]
d.items()
dict_items([('x', 96), ('y', 87), ('z', 86), ('a', 68), ('b', 61), ('c', 75)])
#方案二:傳遞sorted函式的key引數
sorted(d.items(),key=lambda x:x[1])
[('b', 61), ('a', 68), ('c', 75), ('z', 86), ('y', 87), ('x', 96)]
5.如何快速找到多個字典中的公共鍵(key)
from random import randint,sample
from random import randint,sample
# 取樣
sample('abcdef',3)
['e', 'd', 'a']
sample('abcdef',randint(3,6))
['a', 'd', 'e', 'c']
# 找出s1,s2,s3中都存在的key
# 方案一:遍歷
s1 = {x:randint(1,4) for x in sample('abcdef',randint(3,6))}
s1
{'c': 1, 'b': 2, 'e': 3, 'd': 3, 'f': 1, 'a': 2}
s2 = {x:randint(1,4) for x in sample('abcdef',randint(3,6))}
s3 = {x:randint(1,4) for x in sample('abcdef',randint(3,6))}
s2
{'a': 3, 'f': 1, 'c': 1, 'b': 2, 'd': 4, 'e': 4}
s3
{'a': 3, 'd': 1, 'e': 1}
res = []
for k in s1:
if k in s2 and k in s3:
res.append(k)
res
['e', 'd', 'a']
# 方案二:使用集合
s1
{'c': 1, 'b': 2, 'e': 3, 'd': 3, 'f': 1, 'a': 2}
s1.keys()
dict_keys(['c', 'b', 'e', 'd', 'f', 'a'])
s2.keys()
dict_keys(['a', 'f', 'c', 'b', 'd', 'e'])
s1.keys() & s2.keys() & s3.keys()
{'a', 'd', 'e'}
# 方案三:使用map和reduce
# Python3裡,map返回的結果是迭代器(iterator)
list(map(dict.keys,[s1,s2,s3]))
[dict_keys(['c', 'b', 'e', 'd', 'f', 'a']),
dict_keys(['a', 'f', 'c', 'b', 'd', 'e']),
dict_keys(['a', 'd', 'e'])]
from functools import reduce
# reduce() 函式會對引數序列中元素進行累積。
reduce(lambda a,b:a & b,map(dict.keys,[s1,s2,s3]))
{'a', 'd', 'e'}
6.如何讓字典保持有序
d = {}
d['Tom'] = (1,35)
d['Bob'] = (2,37)
d['Kate'] = (3,45)
d
{'Tom': (1, 35), 'Bob': (2, 37), 'Kate': (3, 45)}
# python3.6之後字典有序,按照資料存入的順序
for k in d:
print(k)
Tom
Bob
Kate
# 有序字典OrderedDict
from collections import OrderedDict
d = OrderedDict()
d['Tom'] = (1,35)
d['Bob'] = (2,37)
d['Kate'] = (3,45)
for k in d:
print(k)
Tom
Bob
Kate
from time import time
from random import randint
from collections import OrderedDict
d = OrderedDict()
players =list('ABCDEFGH')
start = time()
for i in range(8):
'''模擬選手比賽消耗時間並存入字典中'''
input()
p = players.pop(randint(0,7-i))
end = time()
print(i + 1, p, end - start,sep=' ')
d[p] = (i + 1, end - start)
print('-' * 30)
for k in d:
print(k, d[k])
1 B 3.176684856414795
2 A 3.636547327041626
3 G 3.978159189224243
4 E 4.341858386993408
5 D 4.702983379364014
6 F 5.248721599578857
7 C 5.690965414047241
8 H 6.034142017364502
------------------------------
B (1, 3.176684856414795)
A (2, 3.636547327041626)
G (3, 3.978159189224243)
E (4, 4.341858386993408)
D (5, 4.702983379364014)
F (6, 5.248721599578857)
C (7, 5.690965414047241)
H (8, 6.034142017364502)
7.如何實現使用者的歷史記錄功能(最多n條)
from collections import deque
# 建立雙向佇列
q = deque([], 5)
q
deque([])
q.append(1)
q.append(2)
q.append(3)
q.append(4)
q.append(5)
q
deque([1, 2, 3, 4, 5])
q.append(6)
q
deque([2, 3, 4, 5, 6])
from random import randint
from collections import deque
N = randint(0, 100)
history = deque([], 5)
def guess(k):
if k == N:
print('Right')
return True
if k < N:
print('%s is less-than N' % k)
else:
print('%s is greater-than N' % k)
return False
while True:
line = input('Please input a number:')
if line.isdigit():
k = int(line)
history.append(k)
if guess(k):
break
elif line == 'history' or line == 'h':
print(list(history))
Please input a number:50
50 is less-than N
Please input a number:80
80 is less-than N
Please input a number:90
90 is less-than N
Please input a number:91
91 is less-than N
Please input a number:92
92 is less-than N
Please input a number:93
93 is less-than N
Please input a number:h
[80, 90, 91, 92, 93]
Please input a number:95
95 is greater-than N
Please input a number:94
Right
import pickle
q
deque([2, 3, 4, 5, 6])
# 將資料存入檔案
pickle.dump(q,open('history','wb'))
# 讀取檔案
q2 = pickle.load(open('history','rb'))
q2
deque([2, 3, 4, 5, 6])