Próbuję złapać pierwszą wartość na wielu listach wewnątrz listy i przechowywać, ile razy powtarza, jeśli jest więcej niż raz w słownik / Hash.

coordinates = [
        ['bg1955', '47.6740° N', '122.1215° W'],
        ['bg1955', '47.6101° N', '122.2015° W'],
        ['bg1955', '47.6062° N', '122.3321° W'],
        ['sj1955', '37.3318° N', '122.0312° W']
    ]

Kiedy próbuję wykonać następujące czynności:

my_dict = {row[0]:coordinates.count(row[0]) for row in coordinates}

Wartość my_dict staje się:

{'sj1955': 0, 'bg1955': 0}

Zamiast:

{'bg1955': 3}

Jak uzyskać powyższe w Python3? Oryginalna próbka danych miałaby ponad 20 000 list na jednej liście zamiast tylko 4 wymienione powyżej.

EDYTOWAĆ: Kiedy wspominam certain, mam na myśli szczególne miejsce w każdym wierszu, który byłby wiersz [0], nie tylko powracający tylko 1 wynik w słowniku. Gdyby było wiele różnych wartości, które powtarzały się, doprowadziłoby to do tego, jak chcę przechowywać dowolną wielokrotną wartość, powiedzmy, czy SW1950 był na 20 listach, a JB1994 był w 393 listach, byłoby:

{'bg1955': 3, 'sw1950': 20, 'jb1994': 393}
0
Daniel Plas Rivera 28 czerwiec 2017, 02:35

3 odpowiedzi

Najlepsza odpowiedź

Powodem, dla którego twoje istniejące podejście nie działa, jest dlatego, że próbujesz to zrobić:

>>> x = [[1, 1, 1]]
>>> x.count(1)

Teraz, myślisz, że to powróci 3, ponieważ 1 jest obecny 3 razy. Jednak to właśnie powraca:

0

Powodem jest dlatego, że te elementy znajdują się na zagnieżdżonej liście, a .count() nie liczy zagnieżdżonych elementów.

Kontrast powyższy:

>>> x = [1, 1, 1]
>>> x.count(1)
3

To ma sens, ponieważ te 1 s nie są na zagnieżdżonej liście.

Jednym z obejścia jest użycie collections.Counter:

from collections import Counter

coordinates = [
        ['bg1955', '47.6740° N', '122.1215° W'],
        ['bg1955', '47.6101° N', '122.2015° W'],
        ['bg1955', '47.6062° N', '122.3321° W'],
        ['sj1955', '37.3318° N', '122.0312° W']
    ]

count = Counter()

for coord in coordinates:
    count[coord[0]] += 1

print(count)

Wynik:

Counter({'bg1955': 3, 'sj1955': 1})

Teraz możesz sondować tego dyktatu dla liczby tego, który chcesz. Jeśli chcesz wyodrębnić duplikaty, możesz to zrobić:

print({ k : count[k] for k in count if count[k] > 1})

To wydruki {'bg1955': 3}.

7
cs95 28 czerwiec 2017, 06:15

Korzystanie z collections.Counter:

>>> from collections import Counter
>>> Counter(c[0] for c in coordinates)
Counter({'bg1955': 3, 'sj1955': 1})
>>> dict(Counter(c[0] for c in coordinates))  # If you want dictionary, not Counter
{'bg1955': 3, 'sj1955': 1}

Jeśli chcesz tylko powielać tylko klucz, filtruj je po tworzeniu licznika.

>>> counts = Counter(c[0] for c in coordinates)
>>> {key: value for key, value in counts.items() if value > 1}
{'bg1955': 3}
4
falsetru 28 czerwiec 2017, 03:46

Możesz użyć defaultdict:

from collections import defaultdict

d = defaultdict(int)

coordinates = [
    ['bg1955', '47.6740° N', '122.1215° W'],
    ['bg1955', '47.6101° N', '122.2015° W'],
    ['bg1955', '47.6062° N', '122.3321° W'],
    ['sj1955', '37.3318° N', '122.0312° W']
]

for i in coordinates:
    d[i[0]] += 1

print dict(d)

Wynik:

{'sj1955': 1, 'bg1955': 3}

Używanie licznika:

new_vals = map(list, zip(*coordinates))

print Counter(new_vals[0])
5
Ajax1234 27 czerwiec 2017, 23:39