💻 آخرین فرصت یادگیری برنامه‌نویسی با آفر ویژه قبل از افزایش قیمت در ۵ آذر ماه (🎁 به همراه یک هدیه ارزشمند )
۰ ثانیه
۰ دقیقه
۰ ساعت
۲ Reza Mobaraki
بهینه سازی count در پایتون
پیمان رشیدی حل شده توسط پیمان رشیدی

سلام دوستان
 

توی این جلسه استاد یه چالشی رو مطرح کردن که باتوجه به اینکه تابع count در قطعه کد زیر سه بار رشته رو پیمایش میکنه که برد و باخت و مساوی رو بدست بیاره ( ما باید یه بار پیمایش کنیم )
 

def parse_result(team):
    return dict(
        name=team['name'],
        win=team['result'].count(['w']),
        draw=team['result'].count('d'),
        lose=team['result'].count('l')
    )

 راه حل حریصانه ( greedy ) قطعه کد این میتونه باشه (البته فکر کنم پایتونیک نباشه :)
اما فقط رشته رو ما یک بار پیمایش میکنیم

def parse_result_greedy(team):
    win = 0
    draw = 0
    lose = 0
    for i in team['result']:
        if i == 'w':
            win += 1
        if i == 'd':
            draw += 1
        if i == 'l':
            lose += 1
    team.update(win=win, draw=draw, lose=lose)
    team.pop('result')
    return team
➜  map-filter-lambda python3 main.py
{'name': 'tractor', 'win': 14, 'draw': 8, 'lose': 7}
{'name': 'sepahan', 'win': 12, 'draw': 12, 'lose': 5}
{'name': 'esteghlal', 'win': 13, 'draw': 11, 'lose': 5}
{'name': 'persepolis', 'win': 20, 'draw': 4, 'lose': 5}

و نکته دیگه اینکه اگر بخواییم تابع count رو فقط یکبار تو کدمون صدا بزنیم ولی بازم مرتبه زمانیش (n) هست 

def check_frequency(team):
    freq = {}
    for i in set(team['result']):
        freq[i] = team['result'].count(i)
    team.update(dict(win=freq['w'], draw=freq['d'], lose=freq['l']))
    team.pop('result')
    return team
 # or we can def this
 def check_freq(team):
    return {i: team.count(i) for i in set(team)}

اگر کسی راه حل دیگه رو میدونه ممنون میشم بزاره :)
موفق باشید ? ?

سلام رضا

 

چیزی که نوشتی درسته. اما بعد از if اول اگر elif بذاری بهینه‌تر هستش. دلیلش رو هم قطعا خودت میدونی. اون i هم به نظرم توی پایتون زیاد جالب نیست. برای همین عوضش کردم. 

 

def parse_result_greedy(team):
    win = 0
    draw = 0
    lose = 0
    for score in team['result']:
        if score == 'w':
            win += 1
        elif score == 'd':
            draw += 1
        elif score == 'l':
            lose += 1
    team.update(win=win, draw=draw, lose=lose)
    team.pop('result')
    return team

 

اینجوری هم میشه نوشت احتمالا ( توی خود پایتون تست کردم این کد رو ) و قطعا مث کد بالا بهینه نیست.

 

def parse_result_greedy(team):
    win = 0
    draw = 0
    lose = 0
    for score in team['result']:
        win += 1 if if score == 'w' else None 
        draw += 1 elif score == 'd' else None
        lose += 1 if score == 'l' else None
    team.update(win=win, draw=draw, lose=lose)
    team.pop('result')
    return team

 

 

بهترین پاسخ
پیمان رشیدی ۱۰ اسفند ۱۳۹۹، ۲۰:۴۸

چون نمیشه پست قبلیم رو ویرایش کنم، این تکه کدم رو اصلاح میکنم 

def parse_result_greedy(team):
    win = 0
    draw = 0
    lose = 0
    for score in team['result']:
        win += 1 if score == 'w' else None 
        draw += 1 if score == 'd' else None
        lose += 1 if score == 'l' else None
    team.update(win=win, draw=draw, lose=lose)
    team.pop('result')
    return team

 

پیمان رشیدی ۱۰ اسفند ۱۳۹۹، ۲۲:۴۳