পাইথন: ডিকের তালিকা, যদি উপস্থিত থাকে একটি ডিক মান, যদি একটি নতুন ডিক সংযোজন না হয়


107

আমি এরকম কিছু করতে চাই।

list_of_urls = ['http://www.google.fr/', 'http://www.google.fr/', 
                'http://www.google.cn/', 'http://www.google.com/', 
                'http://www.google.fr/', 'http://www.google.fr/', 
                'http://www.google.fr/', 'http://www.google.com/', 
                'http://www.google.fr/', 'http://www.google.com/', 
                'http://www.google.cn/']

urls = [{'url': 'http://www.google.fr/', 'nbr': 1}]

for url in list_of_urls:
    if url in [f['url'] for f in urls]:
         urls[??]['nbr'] += 1
    else:
         urls.append({'url': url, 'nbr': 1})

আমি কিভাবে করব ? আমি জানি না যে এটি সম্পাদনা করতে টিপলটি নেওয়া উচিত বা টিপল সূচকগুলি বের করতে হবে?

কোন সাহায্য ?

উত্তর:


207

জিনিসগুলি সংগঠিত করার এটি একটি খুব অদ্ভুত উপায়। আপনি যদি কোনও অভিধানে সঞ্চয় করেন তবে এটি সহজ:

# 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

গুনের একটি অভিধান আপডেট করার জন্য এই কোডটি পাইথনের সাধারণ "প্যাটার্ন"। এটি এত সাধারণ যে একটি বিশেষ ডেটা কাঠামো রয়েছে, defaultdictএটি আরও সহজ করার জন্য তৈরি করা হয়েছে:

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

আপনি যদি defaultdictকোনও কী ব্যবহার করে অ্যাক্সেস করেন এবং কীটি ইতিমধ্যে এর মধ্যে নেই defaultdict, কীটি স্বয়ংক্রিয়ভাবে একটি ডিফল্ট মান সহ যুক্ত হয়। defaultdictCallable লাগে আপনি পাস, এবং ডিফল্ট মান পেতে এটা কল। এই ক্ষেত্রে, আমরা ক্লাসে পাস করেছি int; পাইথন যখন int()এটি কল করে তখন এটি একটি শূন্য মান দেয়। সুতরাং, আপনি প্রথমবার কোনও ইউআরএল রেফারেন্স করলে তার গণনা শূন্যে শুরু হয় এবং তারপরে আপনি একটিতে গণনা যুক্ত করেন।

তবে গণনাগুলিতে পরিপূর্ণ একটি অভিধানও একটি সাধারণ প্যাটার্ন, সুতরাং পাইথন একটি ব্যবহারের জন্য প্রস্তুত ক্লাস সরবরাহ করে: containers.Counter আপনি কেবল Counterক্লাসে কল করে কোনও উদাহরণ তৈরি করেন, কোনও পুনরাবৃত্তিযোগ্য স্থানে চলে যাওয়া; এটি এমন একটি অভিধান তৈরি করে যেখানে কীগুলি পুনরাবৃত্তযোগ্য থেকে মানগুলি হয় এবং মানগুলি কতবার পুনরাবৃত্তীয়গুলিতে কী উপস্থিত হয়েছিল তা গণনা করা হয়। উপরের উদাহরণটি তখন পরিণত হয়:

from collections import Counter  # available in Python 2.7 and newer

urls_d = Counter(list_of_urls)

আপনি যদি দেখিয়েছিলেন এমনভাবেই যদি আপনার সত্যিই প্রয়োজন হয় তবে সবচেয়ে সহজ এবং দ্রুততম উপায় হ'ল এই তিনটি উদাহরণের যে কোনও একটি ব্যবহার করুন এবং তারপরে আপনার যা প্রয়োজন তা তৈরি করুন।

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()]

আপনি যদি পাইথন ২.7 বা তার থেকেও বেশি নতুন ব্যবহার করে থাকেন তবে আপনি এটি ওয়ান-লাইনারে করতে পারেন:

from collections import Counter

urls = [{"url": key, "nbr": value} for key, value in Counter(list_of_urls).items()]

আমি এটি একটি জাঙ্গো টেমপ্লেটে প্রেরণ করতে পছন্দ করি যাতে আমি এটি করতে পারি: ইউআরএলগুলিতে আপনার জন্য% {%%:।। U.nbr}} {% endfor%}
নাতিম

3
আপনি url.items%} {{url} in: url.items%}} {l% endfor%} এর জন্য {% এখনও করতে পারেন
স্টিফ্যানউ

160

ডিফল্ট ব্যবহার করে কাজ করে তবে তা করে:

urls[url] = urls.get(url, 0) + 1

ব্যবহার করে .getআপনি এটির অস্তিত্ব না থাকলে ডিফল্ট রিটার্ন পেতে পারেন। ডিফল্টরূপে এটি কোনওটি নয়, তবে আমি আপনাকে প্রেরণ করেছি, তবে এটি 0 হবে।


12
প্রকৃতপক্ষে আমি মনে করি এটি সেরা উত্তর, যেহেতু প্রদত্ত অভিধানটিতে এটি অজ্ঞেয়বাদী, যা একটি বিশাল বোনাস ইমো।
বাউনার

এটি একটি দুর্দান্ত পরিষ্কার সমাধান।
ডিলান হগ

1
এই উত্তর হওয়া উচিত। দক্ষ, পরিষ্কার এবং বিন্দু !! আমি আশা করি স্ট্যাকওভারফ্লো সম্প্রদায়কে প্রশ্ন পোস্টারের পাশাপাশি উত্তরটি সিদ্ধান্ত নিতে দেয়।
মওইনয়ে

সত্যিকার অর্থে এই উত্তরটি ঠিক মতো কাজ না করা পছন্দ করুন key বা ভাল ... আরও কিছু পদক্ষেপের প্রয়োজন ...
সিড্রিক


17

এটি সর্বদা আমার পক্ষে ভাল কাজ করে:

for url in list_of_urls:
    urls.setdefault(url, 0)
    urls[url] += 1

3

এটা ঠিক আপনার উপায়ে করতে? আপনি ... অন্য স্ট্রাকচারের জন্য ব্যবহার করতে পারেন

for url in list_of_urls:
    for url_dict in urls:
        if url_dict['url'] == url:
            url_dict['nbr'] += 1
            break
    else:
        urls.append(dict(url=url, nbr=1))

তবে এটি বেশ অবহেলিত। আপনি কি সত্যিই পরিদর্শন করা url গুলিকে একটি তালিকা হিসাবে সংরক্ষণ করতে হবে? উদাহরণস্বরূপ, আপনি এটি url স্ট্রিং দ্বারা সূচিযুক্ত একটি ডিক হিসাবে সাজান, তবে এটি উপায় পরিষ্কার হবে:

urls = {'http://www.google.fr/': dict(url='http://www.google.fr/', nbr=1)}

for url in list_of_urls:
    if url in urls:
        urls[url]['nbr'] += 1
    else:
        urls[url] = dict(url=url, nbr=1)

দ্বিতীয় উদাহরণে কয়েকটি বিষয় লক্ষণীয়:

  • কোনও একক পরীক্ষার সময় কীভাবে ডিক ব্যবহারের urlsমাধ্যমে পুরো urlsতালিকার মধ্য দিয়ে যাওয়ার প্রয়োজন সরিয়ে দেয় তা দেখুন url। এই পদ্ধতির দ্রুত হবে।
  • dict( )ধনুর্বন্ধনী পরিবর্তে ব্যবহার করা আপনার কোডকে ছোট করে তোলে
  • ব্যবহার list_of_urls, urlsএবং urlপরিবর্তনশীল নামের কোড বেশ বিশ্লেষণ করতে কঠিন করা হয়েছে। আরও পরিষ্কার কিছু যেমন urls_to_visit, urls_already_visitedএবং যেমন খুঁজে পাওয়া ভাল current_url। আমি জানি, এটি দীর্ঘ। তবে এটা পরিষ্কার।

এবং অবশ্যই আমি ধরে নিচ্ছি যে dict(url='http://www.google.fr', nbr=1)এটি আপনার নিজের ডেটা কাঠামোর সরলকরণ, কারণ অন্যথায়, urlsকেবল এটি হতে পারে:

urls = {'http://www.google.fr':1}

for url in list_of_urls:
    if url in urls:
        urls[url] += 1
    else:
        urls[url] = 1

যা পূর্বনির্ধারিত অবস্থানের সাথে খুব মার্জিত হতে পারে :

urls = collections.defaultdict(int)
for url in list_of_urls:
    urls[url] += 1

দ্বিতীয় সংস্করণটি ভাল, যেহেতু আমি ডিককে পরে তালিকা হিসাবে রূপান্তর করতে পারি।
নাতিম

3

প্রথমবার ব্যতীত, প্রতিবার কোনও শব্দকে if স্টেটমেন্টের পরীক্ষা ব্যর্থ হতে দেখা যায়। আপনি যদি একটি বিশাল সংখ্যক শব্দ গণনা করেন তবে অনেকগুলি সম্ভবত একাধিকবার ঘটবে। এমন একটি পরিস্থিতিতে যেখানে কোনও মানের সূচনা কেবল একবার ঘটতে চলেছে এবং সেই মানটির বর্ধন অনেক বার ঘটবে তা চেষ্টা করার স্টেটমেন্ট ব্যবহার করা সস্তা che

urls_d = {}
for url in list_of_urls:
    try:
        urls_d[url] += 1
    except KeyError:
        urls_d[url] = 1

আপনি এই সম্পর্কে আরও পড়তে পারেন: https://wiki.python.org/moin/PythonSpeed/PerformanceTips

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.