Itu cara yang sangat aneh untuk mengatur sesuatu. Jika Anda menyimpan dalam kamus, ini mudah:
# This example should work in any version of Python.
# urls_d will contain URL keys, with counts as values, like: {'http://www.google.fr/' : 1 }
urls_d = {}
for url in list_of_urls:
if not url in urls_d:
urls_d[url] = 1
else:
urls_d[url] += 1
Kode untuk memperbarui kamus hitungan ini adalah "pola" umum di Python. Sangat umum bahwa ada struktur data khusus defaultdict
,, dibuat hanya untuk membuatnya lebih mudah:
from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
Jika Anda mengakses defaultdict
menggunakan kunci, dan kuncinya belum ada di dalam defaultdict
, kunci tersebut secara otomatis ditambahkan dengan nilai default. The defaultdict
mengambil callable yang Anda berikan, dan memanggilnya untuk mendapatkan nilai default. Dalam hal ini, kami lulus di kelas int
; ketika Python memanggilnya int()
mengembalikan nilai nol. Jadi, pertama kali Anda mereferensikan URL, hitungannya diinisialisasi ke nol, lalu Anda menambahkan satu ke hitungan.
Tetapi kamus yang penuh hitungan juga merupakan pola umum, jadi Python menyediakan kelas yang siap digunakan: containers.Counter
Anda cukup membuat sebuah Counter
instance dengan memanggil kelas tersebut, meneruskan iterable apa pun; itu membangun kamus di mana kuncinya adalah nilai dari iterable, dan nilainya dihitung dari berapa kali kunci muncul di iterable. Contoh di atas kemudian menjadi:
from collections import Counter # available in Python 2.7 and newer
urls_d = Counter(list_of_urls)
Jika Anda benar-benar perlu melakukannya seperti yang Anda tunjukkan, cara termudah dan tercepat adalah menggunakan salah satu dari tiga contoh ini, dan kemudian membangun yang Anda butuhkan.
from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
urls = [{"url": key, "nbr": value} for key, value in urls_d.items()]
Jika Anda menggunakan Python 2.7 atau yang lebih baru, Anda dapat melakukannya dalam satu baris:
from collections import Counter
urls = [{"url": key, "nbr": value} for key, value in Counter(list_of_urls).items()]
Menggunakan default berfungsi, tetapi begitu juga:
menggunakan
.get
, Anda bisa mendapatkan pengembalian default jika tidak ada. Secara default tidak ada, tetapi dalam kasus saya mengirim Anda, itu akan menjadi 0.sumber
Gunakan defaultdict :
sumber
Ini selalu berfungsi dengan baik untuk saya:
sumber
Untuk melakukannya persis dengan cara Anda? Anda dapat menggunakan struktur for ... else
Tapi ini sangat tidak elegan. Apakah Anda benar-benar harus menyimpan url yang dikunjungi sebagai DAFTAR? Jika Anda mengurutkannya sebagai dict, diindeks oleh string url, misalnya, itu akan jauh lebih bersih:
Beberapa hal yang perlu diperhatikan dalam contoh kedua itu:
urls
menghilangkan kebutuhan untuk menelusuri seluruhurls
daftar saat menguji satu singleurl
. Pendekatan ini akan lebih cepat.dict( )
sebagai pengganti tanda kurung membuat kode Anda lebih pendeklist_of_urls
,urls
danurl
sebagai nama variabel membuat kode cukup sulit untuk diurai. Lebih baik menemukan sesuatu yang lebih jelas, sepertiurls_to_visit
,urls_already_visited
dancurrent_url
. Saya tahu, ini lebih lama. Tapi itu lebih jelas.Dan tentu saja saya berasumsi itu
dict(url='http://www.google.fr', nbr=1)
adalah penyederhanaan struktur data Anda sendiri, karena jika tidak,urls
bisa jadi:Yang bisa menjadi sangat elegan dengan sikap defaultdict :
sumber
Kecuali untuk pertama kalinya, setiap kali sebuah kata terlihat, pengujian pernyataan if gagal. Jika Anda menghitung kata dalam jumlah besar, banyak kata mungkin akan muncul beberapa kali. Dalam situasi di mana inisialisasi nilai hanya akan terjadi sekali dan augmentasi nilai tersebut akan terjadi berkali-kali, lebih murah menggunakan pernyataan percobaan:
Anda dapat membaca lebih lanjut tentang ini: https://wiki.python.org/moin/PythonSpeed/PerformanceTips
sumber