Я начал использовать python для проекта для домашних животных, так как организация этих данных была невозможна в такой программе, как excel. Надеюсь, вы можете дать мне несколько советов о том, как достичь результата, который я ищу. Пожалуйста, извините мою нехватку грамотности на питоне.
У меня есть следующий код, который я упростил, уменьшив количество списков и количество элементов в этих списках, чтобы было легче проиллюстрировать.
import itertools
from collections import Counter
a = list(itertools.permutations([32,36,41],3))
b = list(itertools.permutations([36,32,41],3))
c = list(itertools.permutations([19,31,7],3))
fulllist = a+b+c
print(Counter(map(tuple, fulllist)))
что дает следующий результат:
Counter({(32, 36, 41): 2, (32, 41, 36): 2, (36, 32, 41): 2, (36, 41, 32): 2, (41, 32, 36): 2, (41, 36, 32): 2, (19, 31, 7): 1, (19, 7, 31): 1, (31, 19, 7): 1, (31, 7, 19): 1, (7, 19, 31): 1, (7, 31, 19): 1})
Это уже неплохо, но не обязательно, что мне нужно. Теперь, когда у меня есть первый счет каждой комбинации списков, сгенерированный intertools, мне все равно, о порядке каждого элемента внутри указанного списка. Итак, конечный результат, который я хотел бы получить:
(32, 36, 41): 12
(19, 31, 7): 6
И отсортировано, как я уже писал выше. Я чувствую, что могу ходить по кругу, и, возможно, есть более простой способ получить результат, который я ищу. На самом деле мои списки содержат 15 элементов, и у меня есть около 50 из этих списков для обработки.
Надеюсь, ты сможешь мне помочь. Заранее большое спасибо.
Если вы не считаете перестановки (в этом случае используйте ответ @Martin), и это было просто использовано для создания списка примеров, просто сортировка, чтобы сделать его четким, порядок не имеет значения:
>>>print(Counter(tuple(sorted(x)) for x in fulllist))
Counter({(32, 36, 41): 12, (7, 19, 31): 6})
Если все, что вам нужно, это количество возможных перестановок, то просто вычислите эти числа. Это число просто факториал длины ввода:
import math
permutationcount = math.factorial(len(inputlist))
Если вы создаете перестановки, которые короче len(inputlist)
(например, 3 из 20), тогда формула n!/(n - k)!
n!/(n - k)!
:
n = len(inputlist)
k = 3
permutationcount = math.factorial(n) // math.factorial(n - k)
Конечно, когда k
равно n
, то вы делите на 0 !, что равно 1.
Вы можете отсортировать список входных данных и превратить их в кортеж, чтобы создать ключ в сопоставлении:
from collections import Counter
def count_permutations(lists, k=None):
counts = Counter()
if k is None:
k = len(lists[0])
for l in lists:
key = tuple(sorted(l))
permutationcount = math.factorial(len(l)) // math.factorial(len(l) - k)
counts[key] += permutationcount
return counts
Демо-версия:
>>> count_permutations(([32,36,41], [36,32,41], [19,31,7]), k=3)
Counter({(32, 36, 41): 12, (7, 19, 31): 6})
Конечно, вам не нужно использовать Counter
, но может быть удобно использовать его в любом случае, если вам нужен метод .most_common()
и вы не хотите искать способ сортировки словаря по значению.
c = Counter(map(tuple, fulllist))
l = [ {tuple(sorted(i[0])):i[1]} for i in c.items()]
for e in l:
print(e)
{(32, 36, 41): 2}
{(32, 36, 41): 2}
{(32, 36, 41): 2}
{(32, 36, 41): 2}
{(32, 36, 41): 2}
{(32, 36, 41): 2}
{(7, 19, 31): 1}
{(7, 19, 31): 1}
{(7, 19, 31): 1}
{(7, 19, 31): 1}
{(7, 19, 31): 1}
{(7, 19, 31): 1}
counts = {}
, затемkey = tuple(sorted(inputlist))
иcount = math.factorial(len(inputlist))
иcount = math.factorial(len(inputlist))
counts[key] = counts.get(key, 0) + count
, где `inputlist является одним из эти три входа. Нет необходимости создавать какие-либо перестановки на всех.