简体   繁体   English

连接两个变量名以自动查找列表python中的内容

[英]Concatenating two variable names to automate finding something in list python

I'm a beginner practicing python by making a pokemon battle simulator, and I'm in the process of creating a damage modifier function. 我是一个初学者,通过制作一个口袋妖怪战斗模拟器练习python,我正在创建一个伤害修改器功能。

The idea is: 这个想法是:

If the pokemon's "attack type" is found in "attack_type_2x_dmglist", the pokemon deals twice the damage. 如果在“attack_type_2x_dmglist”中找到了口袋妖怪的“攻击类型”,则口袋妖怪会造成两倍的伤害。 "Very effective" “非常有效”

If the pokemon's "attack type" is found in "attack_type_half_dmglist", the pokemon deals only half the damage. 如果在“attack_type_half_dmglist”中找到了口袋妖怪的“攻击类型”,那么口袋妖怪只能造成一半的伤害。 "Isn't very effective" “效果不是很好”

I've used print to make it easy to debug for now. 我已经使用print来使其易于调试。

To verify this, I've done conditionals for type vs type. 为了验证这一点,我已经完成了类型与类型的条件。

normal_2x_dmglist = []
normal_half_dmglist = ["Rock","Dragon"]

rock_2x_dmglist = ["Fire","Ice","Fly","Bug",]
rock_half_dmglist = ["Fighting","Ground","Steel"]

water_2x_dmglist = ["Fire","Ground","Rock"]
water_half_dmglist = ["Water","Grass","Dragon"]

grass_2x_dmglist = ["Water","Ground","Rock"]
grass_half_dmglist = ["Fire","Grass","Poison","Fly","Bug","Dragon","Steel"]

fighting_2x_dmglist = ["Normal","Ice","Rock","Dark","Steel"]
fighting_half_dmglist = ["Poison","Fly","Psychic","Bug","Fairy"]

ground_2x_dmglist = ["Fire","Electric","Poison","Rock","Steel"]
ground_half_dmglist = ["Grass","Bug"]

electric_2x_dmglist = ["Water","Fly"]
electric_half_dmglist = ["Electric","Grass","Dragon"]

def dmg_modifier(attack_type, receiver_pokemon_type):
    if attack_type == "Normal" and receiver_pokemon_type in normal_2x_dmglist:
        print "Normal deals 2x damage!"
    elif attack_type == "Normal" and receiver_pokemon_type in normal_half_dmglist:
        print "Normal deals 1/2 damage!"
    elif attack_type == "Rock" and receiver_pokemon_type in rock_2x_dmglist:
        print "Rock deals 2x damage!"
    elif attack_type == "Rock" and receiver_pokemon_type in rock_half_dmglist:
        print "Rock deals 1/2x damage!"
    elif attack_type == "Water" and receiver_pokemon_type in water_2x_dmglist:
        print "Water deals 2x damage!"
    elif attack_type == "Water" and receiver_pokemon_type in water_half_dmglist:
        print "Water deals 1/2x damage!"
    elif attack_type == "Grass" and receiver_pokemon_type in grass_2x_dmglist:
        print "Grass deals 2x damage!"
    elif attack_type == "Grass" and receiver_pokemon_type in grass_half_dmglist:
        print "Grass deals 1/2x damage!"
    elif attack_type == "Fighting" and receiver_pokemon_type in fighting_2x_dmglist:
        print "Fighting deals 2x damage!"
    elif attack_type == "Fighting" and receiver_pokemon_type in fighting_half_dmglist:
        print "Fighting deals 1/2x damage!"
    elif attack_type == "Ground" and receiver_pokemon_type in ground_2x_dmglist:
        print "Ground deals 2x damage!"
    elif attack_type == "Ground" and receiver_pokemon_type in ground_half_dmglist:
        print "Ground deals 1/2x damage!"
    elif attack_type == "Electric" and receiver_pokemon_type in electric_2x_dmglist:
        print "Electric deals 2x damage!"
    elif attack_type == "Electric" and receiver_pokemon_type in electric_half_dmglist:
        print "Electric deals 1/2x damage!"
    else:
        print "Type deals 1x damage - stays the same"

This works perfectly, it's just very repetitive and dirty. 这很完美,它只是非常重复和肮脏。

To automate this, I planned to attach the declared "attack type" to the "_2x_dmglist" so that it will automatically call the list. 为了自动执行此操作,我计划将声明的“攻击类型”附加到“_2x_dmglist”,以便它自动调用列表。

First I lowercase the declared attack type, for example "Rock", to make it into rock . 首先,我将声明的攻击类型小写,例如“Rock”,使其成为摇滚 Then I attach it to _2x_dmglist so that it comes out as rock_2x_dmglist . 然后我将它附加到_2x_dmglist,以便它以rock_2x_dmglist形式出现 Then it can find the list. 然后它可以找到列表。

def dmg_modifier_2(attack_type, receiver_pokemon_type):
    lower_case_attack_type = attack_type
    lower_cased_attack_type = lower_case_attack_type.lower()
    if attack_type == attack_type and receiver_pokemon_type in lower_cased_attack_type+_2x_dmglist:
        print attack_type+"deals 2x damage"
    elif attack_type == attack_type and receiver_pokemon_type in lower_cased_attack_type+_2x_dmglist:
        print attack_type+"deals 1/2 damage"
    else:
        print "Not working"

Enter this: 输入:

dmg_modifier_2("Rock","Rock")

Output: 输出:

Traceback (most recent call last):
  File "poke_game_test.py", line 98, in <module>
    dmg_modifier_2("Rock","Rock")
  File "poke_game_test.py", line 90, in dmg_modifier_2
    finder = lower_case_attack_type.lower() + _2x_dmglist
NameError: global name '_2x_dmglist' is not defined

I understand the traceback, but how do I concatenate the two variable names so that the whole thing can be automated? 我理解回溯,但如何连接两个变量名称,以便整个事情可以自动化? In PHP, I was able to do this by just using the + sign, which I tried here. 在PHP中,我能够通过使用+符号来完成此操作,我在这里尝试过。 I also understand that the lower cased "Rock" is also a string, while _2x_dmglist is not. 我也明白,较低的套装“Rock”也是一个字符串,而_2x_dmglist则不是。 I'm just quite confused really if variable concatenation works in python cause I can't find a question similar to it here. 如果变量连接在python中工作,我真的很困惑,因为我在这里找不到类似的问题。

Or is there something fundamentally wrong with my code? 或者我的代码有什么根本错误吗?

Thanks! 谢谢!

I think it's time to introduce classes , but you you can also try dictionaries: 我认为是时候介绍classes ,但是你也可以尝试使用词典:

dict_2x_dmg = {
    "Normal":set([]),
    "Rock":{"Fire","Ice","Fly","Bug"},
    "Water":{"Fire","Ground","Rock"},
    "Grass":{"Water","Ground","Rock"},
    "Fighting":{"Normal","Ice","Rock","Dark","Steel"},
    "Ground":{"Fire","Electric","Poison","Rock","Steel"},
    "Electric":{"Water","Fly"}
}

dict_half_dmg = {
    "Normal":{"Rock","Dragon"},
    "Rock":{"Fighting","Ground","Steel"},
    "Water":{"Water","Grass","Dragon"},
    "Grass":{"Fire","Grass","Poison","Fly","Bug","Dragon","Steel"},
    "Fighting":{"Poison","Fly","Psychic","Bug","Fairy"},
    "Ground":{"Grass","Bug"},
    "Electric":{"Electric","Grass","Dragon"}
}

def dmg_modifier(attack_type, receiver_pokemon_type):
    if receiver_pokemon_type in dict_2x_dmg[attack_type]:
        dmg = "2x"
    elif receiver_pokemon_type in dict_half_dmg[attack_type]:
        dmg = "1/2x"
    else:
        dmg = "1x"

    print "{0} deals {1} damage".format(attack_type, dmg)


>>> dmg_modifier("Water", "Ground")
Water deals 2x damage

Another thing you can do - is to use dictionary of dictionaries: 你可以做的另一件事 - 是使用字典词典:

dict_dmg = {
    "Normal":{"Rock":0.5,"Dragon":0.5},
    "Rock":{"Fighting":0.5,"Ground":0.5,"Steel":0.5,"Fire":2,"Ice":2,"Fly":2,"Bug":2},
    "Water":{"Water":0.5,"Grass":0.5,"Dragon":0.5,"Fire":2,"Ground":2,"Rock":2},
    "Grass":{"Fire":0.5,"Grass":0.5,"Poison":0.5,"Fly":0.5,"Bug":0.5,"Dragon":0.5,"Steel":0.5,"Water":2,"Ground":2,"Rock":2},
    "Fighting":{"Poison":0.5,"Fly":0.5,"Psychic":0.5,"Bug":0.5,"Fairy":0.5,"Normal":2,"Ice":2,"Rock":2,"Dark":2,"Steel":2},
    "Ground":{"Grass":0.5,"Bug":0.5,"Fire":2,"Electric":2,"Poison":2,"Rock":2,"Steel":2},
    "Electric":{"Electric":0.5,"Grass":0.5,"Dragon":0.5,"Water":2,"Fly":2}
}

def dmg_modifier2(attack_type, receiver_pokemon_type, dict_dmg):
    dmg = dict_dmg[attack_type].get(receiver_pokemon_type, 1)

    print "{0} deals {1}x damage".format(attack_type, dmg)

Or you can even use pandas DataFrame : 或者您甚至可以使用pandas DataFrame

>>> import pandas as pd
>>> df_dmg = pd.DataFrame.from_dict(dict_dmg)
>>> df
          Electric  Fighting  Grass  Ground  Normal  Rock  Water
Bug            NaN       0.5    0.5     0.5     NaN   2.0    NaN
Dark           NaN       2.0    NaN     NaN     NaN   NaN    NaN
Dragon         0.5       NaN    0.5     NaN     0.5   NaN    0.5
Electric       0.5       NaN    NaN     2.0     NaN   NaN    NaN
Fairy          NaN       0.5    NaN     NaN     NaN   NaN    NaN
Fighting       NaN       NaN    NaN     NaN     NaN   0.5    NaN
Fire           NaN       NaN    0.5     2.0     NaN   2.0    2.0
Fly            2.0       0.5    0.5     NaN     NaN   2.0    NaN
Grass          0.5       NaN    0.5     0.5     NaN   NaN    0.5
Ground         NaN       NaN    2.0     NaN     NaN   0.5    2.0
Ice            NaN       2.0    NaN     NaN     NaN   2.0    NaN
Normal         NaN       2.0    NaN     NaN     NaN   NaN    NaN
Poison         NaN       0.5    0.5     2.0     NaN   NaN    NaN
Psychic        NaN       0.5    NaN     NaN     NaN   NaN    NaN
Rock           NaN       2.0    2.0     2.0     0.5   NaN    2.0
Steel          NaN       2.0    0.5     2.0     NaN   0.5    NaN
Water          2.0       NaN    2.0     NaN     NaN   NaN    0.5

def dmg_modifier3(attack_type, receiver_pokemon_type, df_dmg):
    dmg = df_dmg[attack_type][receiver_pokemon_type]

    print "{0} deals {1}x damage".format(attack_type, dmg)

Although you can do it like 虽然你可以这样做

globals().get(lower_cased_attack_type+'_2x_dmglist')

where globals is python builtin method that returns dict of all the global variables accessible in the calling method. 其中globals是python builtin方法,它返回调用方法中可访问的所有全局变量的dict。 But I would suggest to store your damage lists in dictionary that would be a better approach. 但我建议将你的伤害清单存储在字典中,这是一种更好的方法。

You should do 你应该做

damages = {
  'rock_2x_dmglist': ["Fire","Ice","Fly","Bug",],
  'rock_half_dmglist': ["Fighting","Ground","Steel"],

  'water_2x_dmglist': ["Fire","Ground","Rock"],
  'water_half_dmglist': ["Water","Grass","Dragon"],
}

then you can do damages.get(lower_cased_attack_type+'_2x_dmglist') 然后你可以做damages.get(lower_cased_attack_type+'_2x_dmglist')

You could do the following: 您可以执行以下操作:

damageDict = {}
damageDict['normal']: {'2x':[], 'half':["Rock","Dragon"]}
damageDict['rock']: {'2x':["Fire","Ice","Fly","Bug",], 'half':["Fighting","Ground","Steel"]}
damageDict['water']: {'2x':["Fire","Ground","Rock"], 'half':["Water","Grass","Dragon"]}
damageDict['grass']: {'2x':["Water","Ground","Rock"], 'half':["Fire","Grass","Poison","Fly","Bug","Dragon","Steel"]}
damageDict['fighting']: {'2x':["Normal","Ice","Rock","Dark","Steel"], 'half':["Poison","Fly","Psychic","Bug","Fairy"]}
damageDict['ground']: {'2x':["Fire","Electric","Poison","Rock","Steel"], 'half':["Grass","Bug"]}
damageDict['electric']: {'2x':["Water","Fly"], 'half':["Electric","Grass","Dragon"]}

# test case
attack_type = 'normal'
receiver_type = 'grass'

if receiver_type in damageDict[attack_type]['2x']:
    print ("%s deals 2x damage!" % (attack_type)
elif receiver_type in damageDict[attack_type]['half']:
    print ("%s deals 0.5x damage!" % (attack_type)
else:
    print ("%s deals 1x damage!" % (attack_type)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM