2010-02-03 11 views
5

W Perl, można wykonać następujące czynnościCo to jest pythonowy odpowiednik wzorca Perla do śledzenia, jeśli coś zostało już zauważone?

for (@foo) { 
    # do something 
    next if $seen{$_}++; 
} 

Chciałbym móc zrobić równowartość w Pythonie, to pomiń blok, jeżeli został wykonany tylko raz.

+2

Wiesz, jak pominąć bieżącą iterację pętli w Pythonie, tak? Wiesz również, jak używać skrótów w Pythonie? A jak korzystać z warunków? Możesz po prostu połączyć to wszystko i masz rozwiązanie. –

+0

Anon, nie, nie wiem, dlatego pytam. "dalej, jeśli $ seen {$ _} ++" ładnie wyraża to, co próbuję zrobić i wydaje się, że ekwiwalenty pythonowe nie wydają się tak eleganckie. Chociaż itertools wydaje się, że może pasować do rachunku za Grega. – jnman

+0

Być może przez "elegancki" masz na myśli "zwięzłe" lub "zwięzłe"? Jest ok, jeśli dla ciebie zwięzłe/zwięzłe oznacza eleganckie, ponieważ piękno jest w oku patrzącego, jednak proszę powstrzymać się od używania subiektywnych warunków, kiedy prosisz o pomoc innych; Ty i tylko Ty wiesz, co jest dla ciebie eleganckie. – tzot

Odpowiedz

11
seen = set() 
for x in foo: 
    if x in seen: 
     continue 
    seen.add(x) 
    # do something 

Więcej informacji można znaleźć w dokumentacji set.

Również przykłady na dole dokumentacji modułu itertoolsunique_everseen zawiera generator, którego można użyć tak:

for x in unique_everseen(foo): 
    # do something 
+0

Dzięki. Wygląda na to, że unique_everseen może pasować do rachunku, chociaż wydaje się być wymieniony jako opcjonalny przepis, zamiast być częścią modułu. – jnman

+0

jnman, nie pozwól nikomu wymusić na sobie Pythona. Chodzi mi o to, że ze sposobu, w jaki zdecydujesz się pisać swoje komentarze, oczywiste jest, że w najlepszym przypadku Python jest złem koniecznym (być może jest to wymóg pracy), a jego biblioteka bardzo brakuje (w przeciwieństwie do, powiedzmy, wspaniałego CPAN). – tzot

+0

Jestem o wiele bardziej komfortowe przy użyciu perl niż Python. Jednak ze względu na niektóre rzeczy, nad którymi obecnie pracuję, muszę użyć python zamiast stąd pytania. Wydaje się, że ten konkretny perl (ism) jest wystarczająco użyteczny (dla mnie), że jestem nieco zaskoczony, że nie ma odpowiednika "zwięzłej" wersji w Pythonie (aby użyć twoich słów). – jnman

1
seen={} 
for item in foo: 
    if seen.has_key(item): 
     seen[item]+=1 
     continue # continue is optional, just to illustrate the "next" in Perl 
    else: 
     seen[item]=1 
+0

Alternatywnie 'from collections import defaultdict; seen = defaultdict (int); dla przedmiotu w foo: seen [element] + = 1; jeśli widoczny [element]> 1: kontynuuj; #rest of code' (z właściwym wcięciem, oczywiście.) –

+0

tak, +1 za to. Ale myślę, że nadal jestem starą szkołą, więc to działa dla wersji <2.4+ – ghostdog74

1

Jeśli nie dbają o porządek rzeczy w foo, i tylko to, że unikatowe elementy są iterowane, wtedy rozwiązanie jest łatwiejsze: znacznie.

for x in set(foo): 
    do something 
Powiązane problemy