python 진급: 제1장(데이터 구조와 알고리즘)

15005 단어

문제1: 목록, 사전, 집합에서 조건에 따라 데이터를 어떻게 선별합니까?


문제 내용: 목록의 마이너스를 어떻게 찾아냅니까?어떻게 사전의 값이 어떤 수치보다 큰 항목을 선별합니까?어떻게 집합에서 3으로 정제될 수 있는 원소를 선별합니까?
해결 방안: 목록에 대해 Filter 함수와 목록 해석을 사용할 수 있습니다.
>>> from random import randint 
>>> data = [ randint(-10,10) for _ in range(10)] 
>>> data 
[-4, 0, 8, -2, -5, -9, 6, 5, 6, 6]
>>> filter(lambda x: x >=0,data) 

 , python3 filter , list() 。
>>> list(filter(lambda x: x >=0,data)) 
[0, 8, 6, 5, 6, 6]
>>> [ x for x in data if x>= 0] 
[0, 8, 6, 5, 6, 6]

위의 두 가지 방법 중, 목록 해석에 걸리는 시간은 Filter () 함수보다 적다.
사전에서 사전 구문을 사용합니다.
 
>>> d = { x: randint(60,100) for x in range(1,21)} 
>>> d
{1: 97, 2: 100, 3: 62, 4: 66, 5: 87, 6: 89, 7: 66, 8: 79, 9: 96, 10: 76, 11: 81, 12: 61, 13: 100, 14: 90, 15: 94, 16: 74,
 17: 80, 18: 76, 19: 81, 20: 82}
 90 
>>> {k:v for k,v in d.items() if v>90} 
{1: 97, 2: 100, 15: 94, 13: 100, 9: 96}

컬렉션의 경우 컬렉션 해석을 사용합니다.
>>> s = set(data) 
>>> { x for x in s  if x % 3 ==0}
{0, 6, -9}

문제2: 어떻게 원조의 모든 요소를 명명하여 프로그램의 가독성을 높입니까?


질문 내용: 학생 정보 시스템에서 데이터는 고정 형식: (이름, 나이, 성별, 메일주소)
학생 수가 매우 많기 때문에 저장 비용을 줄이기 위해 모든 학생의 정보를 원조로 표시한다. ('Wex', 24,'female',[email protected]') ('Fangyw',23,female,'[email protected]') ('Pandz',25,male,'[email protected]') ......
방문할 때, 우리는 인덱스 (index) 를 사용하여 접근합니다. 대량의 인덱스는 프로그램의 가독성을 떨어뜨립니다. 어떻게 이 문제를 해결합니까?
해결 방안: 방안1: 다른 언어와 유사한 매거 유형을 정의한다. 즉, 일련의 수치 상수를 정의한다.프로젝트 2: 표준 라이브러리에서collections를 사용합니다.내장된 Tuple 대신 namedtuple
먼저 사용 열거를 보십시오:
>>> NAME = 0 
>>> AGE = 1 
>>> SEX = 2 
>>> EMAIL = 3 
>>> student = ('Wex',24,'female','[email protected]') 
>>> student[NAME] 
'Wex'

 
>>> NAME,AGE,SEX,EMAIL=range(4) 
>>> student[NAME] 
'Wex'

다음으로는 Namedtuple을 사용하는 방법을 살펴보겠습니다.
 namedtuple :
┌──────────────────────────────────────────────────────────────────────────────────────────────┐
│ namedtuple: (typename, field_names, verbose=False, rename=False)                             │
│ Returns a new subclass of tuple with named fields.                                           │
│                                                                                              │
│ >>> Point = namedtuple('Point', ['x', 'y'])                                                  │
│ >>> Point.__doc__                   # docstring for the new class                            │
│ 'Point(x, y)'                                                                                │
│ >>> p = Point(11, y=22)             # instantiate with positional args or keywords           │
│ >>> p[0] + p[1]                     # indexable like a plain tuple                           │
│ 33                                                                                           │
│ >>> x, y = p                        # unpack like a regular tuple                            │
│ >>> x, y                                                                                     │
│ (11, 22)                                                                                     │
│ >>> p.x + p.y                       # fields also accessible by name                         │
│ 33                                                                                           │
│ >>> d = p._asdict()                 # convert to a dictionary                                │
│ >>> d['x']                                                                                   │
│ 11                                                                                           │
│ >>> Point(**d)                      # convert from a dictionary                              │
│ Point(x=11, y=22)                                                                            │
│ >>> p._replace(x=100)               # _replace() is like str.replace() but targets named fie │
│ lds                                                                                          │
│ Point(x=100, y=22)                                                                           │
└──────────────────────────────────────────────────────────────────────────────────────────────┘
 tuple 。 , 。

>>> from collections import namedtuple 
>>> namedtuple('Student',['name','age','sex','email']) 

>>> Student = namedtuple('Student',['name','age','sex','email']) 
 
>>> s1 = Student('Wex',24,'female','[email protected]')  
>>> s1 
Student(name='Wex', age=24, sex='female', email='[email protected]')
 
>>> s2 = Student(name='Fyw', age=22, sex='female', email='[email protected]')
>>> s2 
Student(name='Fyw', age=22, sex='female', email='[email protected]')
 
>>> s1.name 
'Wex'
>>> s2.age 
22
 tuple 
>>> type(s1) 

>>> isinstance(s1,tuple) 
True

문제3: 어떻게 열에서 원소의 출현 빈도를 통계합니까?


질문 내용: 1, 랜덤 시퀀스[12, 1, 2, 3, 4, 5, 4, 3, 4, 5,...]에서 가장 많이 나타나는 3개의 요소를 찾았는데 그 출현 횟수는 얼마나 됩니까?2, 어떤 영문 문장의 단어에 대해 주파수 통계를 실시하여 가장 많이 나타난 10개의 단어를 찾았는데, 그것들의 출현 횟수는 얼마나 됩니까?
임의 시퀀스의 경우: 반복 방법을 사용합니다.
>>> from random import randint 
 
>>> data = [randint(0,20) for _ in range(0,30)] 
 , 0 
>>> c = dict.fromkeys(data,0) 
 , 
>>> for x in data:
...     c[x] += 1 
...     
... 
>>> c 
{0: 2, 2: 1, 3: 2, 4: 1, 5: 3, 6: 1, 7: 1, 9: 1, 10: 1, 12: 1, 14: 3, 15: 2, 16: 3, 17: 2, 18: 2, 19: 3, 20: 1}

솔루션:collections를 사용합니다.Counter 대상은 서열을 Counter 구조기에 전송합니다. Counter 대상은 원소의 주파수를 나타내는 사전 Counter입니다.most_commom (n) 방법은 빈도가 가장 높은 n개 요소의 목록을 얻을 수 있습니다. 먼저 Counter 함수의 문법을 보십시오.
┌──────────────────────────────────────────────────────────────────────────────────────────────┐
│ Counter: (*args, **kwds)                                                                     │
│ data                                                                                         │
│ Create a new, empty Counter object.  And if given, count elements                            │
│ from an input iterable.  Or, initialize the count from another mapping                       │
│ of elements to their counts.                                                                 │
│                                                                                              │
│ >>> c = Counter()                           # a new, empty counter                           │
│ >>> c = Counter('gallahad')                 # a new counter from an iterable                 │
│ >>> c = Counter({'a': 4, 'b': 2})           # a new counter from a mapping                   │
│ >>> c = Counter(a=4, b=2)                   # a new counter from keyword args                │
└──────────────────────────────────────────────────────────────────────────────────────────────┘

우리가 생성한 무작위 시퀀스 전송 함수는 통계 결과의 사전으로 되돌아온다
>>> from collections import Counter 
>>> c2 = Counter(data)
>>> c2 
Counter({5: 3, 14: 3, 16: 3, 19: 3, 0: 2, 3: 2, 15: 2, 17: 2, 18: 2, 2: 1, 4: 1, 6: 1, 7: 1, 9: 1, 10: 1, 12: 1, 20: 1})
>>> c2[10]
1
>>> c2[5]
3
>>> c2.most_common(3) 
[(5, 3), (14, 3), (16, 3)]

현재 우리는 한 파일에 대해 단어 주파수를 통계한다.
>>> import re 
 
>>> txt = open('vimrc.txt').read()
 
>>> re.split('\W+',txt)
 Counter 
>>> c3 = Counter(re.split('\W+',txt))
 most_common 
>>> c3.most_common(10)

문제4: 사전의 값 크기에 따라 사전의 항목을 정렬하는 방법


질문 내용: 모 반의 영어 성적은 사전 형식으로 저장: {'wex':98,'fyw':97,'xyx':99...}성적의 높낮이에 따라 학생에 대한 순위를 매기다
해결 방안: 내장 함수sorted1을 사용하여 zip을 이용하여 사전 데이터를 모듈 2로 전환하고sorted 함수를 전달하는 키 매개 변수
방법 1: zip을 사용하여 원조로 변환하여 정렬
In [1]:  from random import  randint   

In [2]: d = {x: randint(60,100) for x in 'xyzabc'}  
 , 
In [3]: sorted(d)  
Out[3]: ['a', 'b', 'c', 'x', 'y', 'z']
 , 
In [4]: (97,'a') > (96,'b') 
Out[4]: True
 , 
In [5]: (97,'a') > (97,'b') 
Out[5]: False

In [6]: d.keys()  
Out[6]: dict_keys(['x', 'b', 'z', 'y', 'c', 'a'])

In [7]: d.values()   
Out[7]: dict_values([88, 76, 96, 78, 62, 68])

In [8]: zip(d.values(),d.keys())  
Out[8]: 

In [9]: type(d.keys()) 
Out[9]: dict_keys
 python3 ,zip list 
In [10]: list(zip(d.values(),d.keys())) 
Out[10]: [(88, 'x'), (76, 'b'), (96, 'z'), (78, 'y'), (62, 'c'), (68, 'a')]

In [11]: sorted(list(zip(d.values(),d.keys()))) 
Out[11]: [(62, 'c'), (68, 'a'), (76, 'b'), (78, 'y'), (88, 'x'), (96, 'z')]

방법2:sorted 함수를 전달하는 키 매개 변수
 items() , 
In [12]: d.items() 
Out[12]: dict_items([('x', 88), ('b', 76), ('z', 96), ('y', 78), ('c', 62), ('a', 68)])
 sorted , key ,x ,lambda 
In [13]: sorted(d.items(),key=lambda x: x[1]) 
Out[13]: [('c', 62), ('a', 68), ('b', 76), ('y', 78), ('x', 88), ('z', 96)]

문제5: 어떻게 여러 사전의 공통 키(key)를 신속하게 찾습니까?


문제 내용: 스페인 축구팀 갑급 리그, 매 라운드 선수 골 통계: 1라운드: {'수아': 1,'메시': 2,'본제마': 1,......}2라운드:{'수아':2,'벨':1,'그리':2,......}3라운드: {'수아':1,'토르':2,'벨':2,......}...전 N라운드에서 매 경기 골을 넣은 선수가 집계됐다.
간단한 스트리밍 사용:
>>> from random import  randint,sample 
 sample 
>>> sample('abcdefg',3) 
['b', 'd', 'a']
 3 6 
>>> sample('abcdefg',randint(3,6)) 
['c', 'd', 'f', 'b', 'a', 'g']
 
>>> s1 = { x: randint(1,4) for x in sample('abcdefg',randint(3,6))} 
>>> s1
{'f': 3, 'e': 3, 'c': 1, 'b': 4, 'g': 2}
>>> s2 = { x: randint(1,4) for x in sample('abcdefg',randint(3,6))} 
>>> s3 = { x: randint(1,4) for x in sample('abcdefg',randint(3,6))} 
>>> s2
{'f': 2, 'd': 1, 'c': 3, 'b': 3, 'g': 4}
>>> s3
{'e': 4, 'c': 3, 'a': 4, 'b': 3}
>>> inlist = []
>>> for k in s1:
...     if k in s2 and  k in s3:
...         inlist.append(k) 
...         
...     
>>> inlist 
['c', 'b']

다른 해결 방안: 집합(set)의 교차 조작을 이용한다. 절차1: 사전의viewkeys() 방법을 사용하여 사전 키스의 집합을 얻는다. (이것은python2의 방법이고,python3은 키스() 방법으로 모든 키를 얻는다) 절차2: 맵 함수를 사용하여 모든 사전의 키스의 집합 절차를 얻는다. 3:reduce 함수를 사용하여 모든 사전의 키스의 집합을 얻는다.
 
>>> s1.keys()
dict_keys(['f', 'e', 'c', 'b', 'g'])
>>> s1.keys() & s2.keys() & s3.keys() 
{'c', 'b'}
 
>>> map(dict.keys,[s1,s2,s3]) 

 map list
>>> reduce(lambda a,b: a & b,map(dict.keys,[s1,s2,s3])) 
Traceback (most recent call last):
  File "", line 1, in 
    reduce(lambda a,b: a & b,map(dict.keys,[s1,s2,s3]))
NameError: name 'reduce' is not defined
 Python 3 ,reduce() , fucntools     
>>> from functools import reduce 
>>> reduce(lambda a,b: a & b,map(dict.keys,[s1,s2,s3]))  
{'c', 'b'}

문제6: 어떻게 사전을 질서정연하게 유지합니까?


문제 내용: 경기 시스템을 프로그래밍하여 시합에 참가한 선수의 프로그래밍 문제를 시간을 재고 선수가 문제를 완성한 후 이 선수의 문제를 풀 때 사전에 기록하여 경기 후 선수명에 따라 성적을 조회하도록 한다.(퀴즈 시간이 짧을수록 성적이 좋다) {'wex':(2,43).'hmm':(5,43),'fyw':(1,23)......경기가 끝난 후, 랭킹 순서에 따라 순서대로 선수의 성적을 인쇄해야 하는데, 어떻게 실현합니까?
솔루션:collections를 사용합니다.OrderedDict는 내장 사전 Dict를 OrderedDict로 대체하고, 순서대로 선수 성적을 OrderedDict에 저장한다.
from collections import OrderedDict 
from random import  randint
from time import time  
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) 
    d[p] = (i+1,end-start) 


print("******")
for k in d:
    print(k,d[k])

 

1 G 1.6133077144622803

2 A 1.9757952690124512

3 D 2.3789286613464355

4 F 2.730335235595703

5 B 3.157444715499878

6 H 3.551867961883545

7 C 3.967583179473877

8 E 4.346914291381836
******
G (1, 1.6133077144622803)
A (2, 1.9757952690124512)
D (3, 2.3789286613464355)
F (4, 2.730335235595703)
B (5, 3.157444715499878)
H (6, 3.551867961883545)
C (7, 3.967583179473877)
E (8, 4.346914291381836)

문제7: 사용자의 역사 기록 기능(최대 n개)을 어떻게 실현합니까?


문제 내용: 현재 우리는 간단한 숫자 맞추기 게임을 제작하여 역사 기록 기능을 추가하여 사용자가 최근에 맞힌 숫자를 표시하는데 어떻게 실현합니까?
해결 방안: 용량이 n인 대기열 저장 기록을 사용합니다. 표준 라이브러리collectios의 deque를 사용합니다. 이중 순환 대기열 프로그램이 종료되기 전에pickle로 대기열 대상을 파일에 저장하고 프로그램을 다시 실행할 때 가져올 수 있습니다.
>>> from collections import deque
 deque 
>>> q = deque([],5) 
>>> q.append(1)
>>> q.append(2)
>>> q.append(3)
>>> q.append(4)
>>> q.append(5)
>>> q
deque([1, 2, 3, 4, 5], maxlen=5)
>>> q.append(6)
>>> q 
deque([2, 3, 4, 5, 6], maxlen=5)

게임 텍스트:
from collections import deque 
from random import randint 

N = randint(0,100)
history = deque([],5) 

def guess(k):
    if k == N:
        print('right')
    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":
        print(list(history))

위의 프로그램은 게임의 기능을 실현하고 다섯 번의 입력을 저장할 수 있다.pickle 모듈의dump()와load() 함수를 사용하여 데이터를 파일에 저장하고 파일에서 읽을 수 있습니다
>>> import pickle
>>> p = ['ew','ferf'] 
>>> pickle.dump(p,open('historyy','wb'))
>>> q2 = pickle.load(open('historyy','rb'))
>>> q2
['ew', 'ferf']

좋은 웹페이지 즐겨찾기