بهینه سازی count در پایتون

پرسیده شده
فعالیت 1124 روز پیش
دیده شده 664 بار
1

سلام دوستان
 

توی این جلسه استاد یه چالشی رو مطرح کردن که باتوجه به اینکه تابع 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)}

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

فایل پیوست

Reza Mobaraki
Reza Mobaraki

8 اسفند 99

1
حذف شده

سلام رضا

 

چیزی که نوشتی درسته. اما بعد از 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

 

 

فایل پیوست

پیمان رشیدی

توسط

پیمان رشیدی

10 اسفند 99

حذف شده
سلام پیمان جان ممنون که این ذکر کردی این موارد رو
Reza Mobaraki

10 اسفند 99

حذف شده
قربان شما توی خط ۷ اشتباها ۲ بار if گذاشتم
پیمان رشیدی

10 اسفند 99

حذف شده
کلا این قسمت رو اشتباه نوشتم.اصلاح میکنم :))) 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
پیمان رشیدی

10 اسفند 99

حذف شده
آقا این چرا اینجوری شد :)))
پیمان رشیدی

10 اسفند 99

1
حذف شده

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

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

 

فایل پیوست

پیمان رشیدی

توسط

پیمان رشیدی

10 اسفند 99

جلسه ادامه آشنایی با توابع بی‌نام و استفاده از lambda در تابع sorted