Ответ 1
Многие люди не знают, что Python позволяет фильтровать результаты понимания списка с помощью if
:
>>> [i for i in range(10) if i % 2 == 0]
[0, 2, 4, 6, 8]
Одной из основных преимуществ python и нескольких других (функциональных) языков программирования является понимание . Они позволяют программистам писать сложные выражения в 1 строке. Сначала они могут вводить в заблуждение, но если кто-то привыкнет к синтаксису, он намного лучше, чем сложный для циклов вложенный.
С учетом сказанного, пожалуйста, поделитесь со мной некоторыми из самых крутых способов использования списков. (Ключ, я просто имею в виду полезный) Это может быть для какого-то конкурса программирования или производственной системы.
Например:
Для выполнения транспонирования матрицы mat
>>> mat = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>> [[row[i] for row in mat] for i in [0, 1, 2]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Пожалуйста, укажите описание выражения и его использование (если это возможно).
Многие люди не знают, что Python позволяет фильтровать результаты понимания списка с помощью if
:
>>> [i for i in range(10) if i % 2 == 0]
[0, 2, 4, 6, 8]
Я часто использую понимание для построения dicts:
my_dict = dict((k, some_func(k)) for k in input_list)
Примечание. Python 3 имеет четкие понимания, поэтому это делается:
my_dict = {k:some_func(k) for k in input_list}
Для построения CSV-подобных данных из списка кортежей:
data = "\n".join(",".join(x) for x in input)
На самом деле не понимание списков, но все же полезно: Создайте список диапазонов из списка "точек резания":
ranges = zip(cuts, cuts[1:])
Сделать транспонирование матрицы mat
:
>>> [list(row) for row in zip(*mat)]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Сгладить список списков:
>>> matrix = [[1,2,3], [4,5,6]]
>>> [x for row in matrix for x in row]
[1, 2, 3, 4, 5, 6]
Если "круто" означает "сумасшедший", мне нравится этот:
def cointoss(n,t):
return (lambda a:"\n".join(str(i)+":\t"+"*"*a.count(i) for i in range(min(a),max(a)+1)))([sum(randint(0,1) for _ in range(n)) for __ in range(t)])
>>> print cointoss(20,100)
3: **
4: ***
5: **
6: *****
7: *******
8: *********
9: *********
10: ********************
11: *****************
12: *********
13: *****
14: *********
15: *
16: **
n и t контролируют количество бросков монет на тест и количество раз, когда тест выполняется и распределение отображается.
Я использую это все время при загрузке разделенных табуляцией файлов с необязательными строками комментария, начинающимися с метки хэша:
data = [line.strip().split("\t") for line in open("my_file.tab") \
if not line.startswith('#')]
Конечно, он работает и для любого другого символа комментария и разделителя.
В настоящее время у меня есть несколько скриптов, которым нужно группировать набор точек в "уровни" по высоте. Предположение состоит в том, что z-значения точек будут свободно кластеризоваться вокруг определенных значений, соответствующих уровням, с большими ишемическими промежутками между кластерами.
Итак, у меня есть следующая функция:
def level_boundaries(zvalues, threshold=10.0):
'''Finds all elements z of zvalues such that no other element
w of zvalues satisfies z <= w < z+threshold.'''
zvals = zvalues[:]
zvals.sort()
return [zvals[i] for i, (a, b) in enumerate(pairs(zvals)) if b-a >= threshold]
"пары" берутся прямо из документации модуля itertools, но для справки:
def pairs(iterable):
'iterable -> (iterable[n], iterable[n+1]) for n=0, 1, 2, ...'
from itertools import izip, tee
first, second = tee(iterable)
second.next()
return izip(first, second)
Приведенный пример использования (мои фактические наборы данных слишком велики для использования в качестве примеров):
>>> import random
>>> z_vals = [100 + random.uniform(-1.5,1.5) for n in range(10)]
>>> z_vals += [120 + random.uniform(-1.5,1.5) for n in range(10)]
>>> z_vals += [140 + random.uniform(-1.5,1.5) for n in range(10)]
>>> random.shuffle(z_vals)
>>> z_vals
[141.33225473458657, 121.1713952666894, 119.40476193163271, 121.09926601186737, 119.63057973814858, 100.09095882968982, 99.226542624083109, 98.845285642062763, 120.90864911044898, 118.65196386994897, 98.902094334035326, 121.2741094217216, 101.18463497862281, 138.93502941970601, 120.71184773326806, 139.15404600347946, 139.56377827641663, 119.28279815624718, 99.338144106822554, 139.05438770927282, 138.95405784704622, 119.54614935118973, 139.9354467277665, 139.47260445000273, 100.02478729763811, 101.34605205591622, 138.97315450408186, 99.186025111246295, 140.53885845445572, 99.893009827114568]
>>> level_boundaries(z_vals)
[101.34605205591622, 121.2741094217216]
Если вы после функционального программирования вдохновили части Python, рассмотрите карту, фильтр, сокращение и zip ---- все предлагаемые в python.