有沒有辦法減少elif我的宣告中的內容?在另一個問題中,我問過某人說我的代碼存在冗余問題,而且確實如此。一般來說,我對 python 和編碼比較陌生,當我查找內容時,總是有點難以理解。
這是我正在談論的代碼塊:
(如果需要,我可以發布其余代碼)
if (random_mon_name.lower()=='normal'):
rangen_mon_name = random.choice(mon_name_type_NORMAL)
break
elif (random_mon_name.lower()=='fire'):
rangen_mon_name = random.choice(mon_name_type_FIRE)
break
elif (random_mon_name.lower()=='water'):
rangen_mon_name = random.choice(mon_name_type_WATER)
break
elif (random_mon_name.lower()=='grass'):
rangen_mon_name = random.choice(mon_name_type_GRASS)
break
elif (random_mon_name.lower()=='electric'):
rangen_mon_name = random.choice(mon_name_type_ELECTRIC)
break
elif (random_mon_name.lower()=='ice'):
rangen_mon_name = random.choice(mon_name_type_ICE)
break
elif (random_mon_name.lower()=='fighting'):
rangen_mon_name = random.choice(mon_name_type_FIGHTING)
break
elif (random_mon_name.lower()=='poison'):
rangen_mon_name = random.choice(mon_name_type_POISON)
break
elif (random_mon_name.lower()=='ground'):
rangen_mon_name = random.choice(mon_name_type_GROUND)
break
elif (random_mon_name.lower()=='flying'):
rangen_mon_name = random.choice(mon_name_type_FLYING)
break
elif (random_mon_name.lower()=='psychic'):
rangen_mon_name = random.choice(mon_name_type_PSYCHIC)
break
elif (random_mon_name.lower()=='bug'):
rangen_mon_name = random.choice(mon_name_type_BUG)
break
elif (random_mon_name.lower()=='ghost'):
rangen_mon_name = random.choice(mon_name_type_GHOST)
break
elif (random_mon_name.lower()=='rock'):
rangen_mon_name = random.choice(mon_name_type_ROCK)
break
elif (random_mon_name.lower()=='dark'):
rangen_mon_name = random.choice(mon_name_type_DARK)
break
elif (random_mon_name.lower()=='dragon'):
rangen_mon_name = random.choice(mon_name_type_DRAGON)
break
elif (random_mon_name.lower()=='steel'):
rangen_mon_name = random.choice(mon_name_type_STEEL)
break
elif (random_mon_name.lower()=='fairy'):
rangen_mon_name = random.choice(mon_name_type_FAIRY)
break
else:
print("You didn't actually enter a type.\nTry Again.")
uj5u.com熱心網友回復:
我建議您這樣創建一個dict:
myDict = {}
myDict['ice'] = mon_name_type_ICE
# ...and so on
這樣您就可以使用一小段代碼訪問它:
rangen_mon_name = random.choice(myDict[random_mon_name.lower()])
您還可以添加try/except塊來模擬您的else:
try:
rangen_mon_name = random.choice(myDict[random_mon_name.lower()])
except KeyError:
print("You didn't actually enter a type.\nTry Again.")
uj5u.com熱心網友回復:
此代碼中存在如此多冗余的根本原因是您必須管理大量變數。
每當您有一堆單獨的變數都包含相同型別的資料時,例如mon_name_type_FIRE和mon_name_type_WATER(我假設這些是與該攻擊型別相關的名稱串列),這是一個強有力的線索,您應該將它們放入一個集合中,例如字典或串列。這不僅減少了代碼中要跟蹤的變數數量,還可以動態訪問這些值,而不是使用大量的復制 粘貼代碼。
例如,如果您將所有不同mon的 s 放入一個dict由其攻擊型別鍵入的密鑰中,而不是創建所有mon_name_type_WHATEVER變數:
mon_by_type = {
"fire": ["charmander", "charmeleon", "charizard"],
"water": ["squirtle", "wartortle", "blastoise"],
# etc
}
您現在可以用單個字典查找替換您的巨型if/鏈:elif
try:
random_mon = random.choice(mon_by_type[random_mon_name.lower()])
except KeyError:
print("You didn't actually enter a type. Try again.")
uj5u.com熱心網友回復:
如果您沒有像mon_name_type_FIRE在代碼的其他區域中那樣使用變數,并且您能夠創建“名稱”查找或字典,那么您肯定會想要這樣做。請參閱 @FLAC-ZOSO 和 @samwise 的答案以幫助您入門。
但是,如果您已經定義了所有這些“名稱”串列并且想要使用“適當的”串列,您可能會考慮從locals()(或globals()).
import random
## ------------------
## You have these pre-defined and want to keep them
## as distinct variables for some reason.
## ------------------
mon_name_type_NORMAL = ["Elf", "Human"]
mon_name_type_FIRE = ["Fire Dwarf", "Cinder Elf"]
## ------------------
## ------------------
## Use a "mob" class and locals() to find the appropriate matching
## list of mob names.
## ------------------
random_mon_name = "Fire"
rmn_key = f"mon_name_type_{random_mon_name.upper()}"
name_options = locals().get(rmn_key, ["**unnamed mob**"])
## ------------------
print(random.choice(name_options))
uj5u.com熱心網友回復:
choices像下面這樣構造一個字典。將攻擊值傳遞給get_attack_values,如果攻擊在 中choices,則將值傳遞mon_name_type_ICE給random.choice()函式。
import random
choices = {
'ice': {'choice': 'mon_name_type_ICE'},
'fire': { 'choice': 'mon_name_type_WATER'}
}
def get_attack_value(attack):
if attack in choices.keys():
rangen_mon_name = random.choice(choices[attack]['choice'])
else:
print("You didn't actually enter a type.\nTry Again.")
get_attack_value('fire')
uj5u.com熱心網友回復:
到目前為止,我最喜歡@Samwise 的答案,因為它使代碼“資料驅動”,因為它不僅消除了所有這些變數,而且還使擴展事情變得微不足道 - 但認為可以通過制作更進一步一本字典本身的創建也是這樣做的。這就是我的意思:
from pprint import pprint
import random
MON_TYPE_NAMES = """\
normal, Normodo, Normalia, Normew
fire, Firaint, Heatoro, Flamala
water, Splashoto, Oceatto, Puddlio
grass, Weedevon, Grassimar, Leafadroon
electric, Enetick, Electol, Litero
ice, Snova, Icello, Colaggro
fighting, Allphist,Lullakick,Bubblow
poison, Poizase, Gunkamight, Aison
ground, Groutal, Moundiflox, Umbron
flying, Wingyu, Sparial, Flogun
psychic, Mindswell, Thinkarva, Psymarine
bug, Bugonite, Flyzaur, Mantile
ghost, Phantini, Spirook, Tortasm
rock, Storilot, Rocoalia, Sedite
dark, Nolite, Dariotte, Nitrash
dragon, Dracat, Wyveron, Randigon
steel, Metalaze, Gearevo, Iromonora
fairy, Faeream, Pixirola, Trixitrite
"""
# Create dictionary from mon type names.
name_to_choices = {v[0]: v[1:] for v in (line.replace(',', '').split()
for line in MON_TYPE_NAMES.splitlines())}
pprint(name_to_choices, sort_dicts=False)
print()
# Select random mon name based on mon type.
random_mon_type = 'Ghost'
if not (choices := name_to_choices.get(random_mon_type.lower())):
print("Unknown mon type")
else:
rangen_mon_name = random.choice(choices)
print(f'random {random_mon_type} name -> {rangen_mon_name}')
uj5u.com熱心網友回復:
這似乎會讓您受益于將所有這些投入到像字典這樣的資料結構中。由于您只是通過完美的 1:1 映射將值設定為其他值,因此實際上為此制作了字典。
random_mon_name_dict = {'normal': random.choice(mon_name_type_NORMAL), 'bug', random.choice(mon_name_type_BUG)}
但顯然對他們所有人來說。
我理解正確嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/449002.html
標籤:Python python-3.x 列表 if 语句
