繁体   English   中英

不附加可迭代对象时可以使用列表理解吗

[英]Can you use a List Comprehension when not appending the iterable

所以我决定开始使用 List Comprehensions,经过一番谷歌搜索后,我设法做到了:

# old way
loaded_sounds = []
for i in assetList_text:
    if i.startswith("loaded_sound"):
        loaded_sounds.append(i.split(',')[1])

# new way
loaded_sounds = [i.split(',')[1] for i in assetList_text if i.startswith("loaded_sound")]

效果很好。 所以我认为 id 继续进行硬 for 循环,这就是列表理解结果与 for 循环结果不匹配的地方。

所以这种转换有点困难,因为它不仅有 2 个“if”语句,而且实际上也没有附加索引。

gsc_files = []
for i in assetList_text:
    if ".gsc" in i:
        d = i.split(',')[-1].replace("\n", "")
        if d not in gsc_files:
            gsc_files.append(d)

所以这打印出来: 6 但是这样:

gsc_files = [i.split(',')[-1].replace("\n", "") for i in assetList_text if ".gsc" in i if i.split(',')[-1].replace("\n", "") not in gsc_files]

它打印出来: 0 所以我不知道它哪里出错了?

此外,在列表理解的主题上,我想知道它们的广度。 可以将以下 2 个 for 循环转换为列表推导吗?

[1]

weapon_files = []
x = join(f"{WAW_ROOT_DIR}/raw/weapons/sp")
for path, subdirs, files in walk(x):
    for fileName in files:
    content = join(x, fileName)
    if content not in weapon_files:
        weapon_files.append(f"{WAW_ROOT_DIR}/raw/weapons/sp/{fileName}")

[2]

gsc_files_dir = []
for path in gsc_files:
if f"{CURRENT_SELECTED_MOD.lower()}" in path:
    dir = join(f"{WAW_ROOT_DIR}/mods/{CURRENT_SELECTED_MOD}/{path}")
    gsc_files_dir.append(dir)
elif os.path.exists(f"{WAW_ROOT_DIR}/mods/{CURRENT_SELECTED_MOD}/{path}"):
    dir = join(f"{WAW_ROOT_DIR}/mods/{CURRENT_SELECTED_MOD}/{path}")
    gsc_files_dir.append(dir)
else:
    dir = join(f"{WAW_ROOT_DIR}/raw/{path}")
    gsc_files_dir.append(dir)

问候,菲尔

编辑:回应“DialFrost”的问题:

f1 = join(f"{WAW_ROOT_DIR}/zone_source/english/assetlist/{CURRENT_SELECTED_MOD}.csv")
f2 = join(f"{WAW_ROOT_DIR}/zone_source/english/assetlist/{CURRENT_SELECTED_MOD}_patch.csv")
f3 = join(f"{WAW_ROOT_DIR}/zone_source/english/assetinfo/{CURRENT_SELECTED_MOD}.csv")
f4 = join(f"{WAW_ROOT_DIR}/zone_source/english/assetinfo/{CURRENT_SELECTED_MOD}_patch.csv")

with open(f1, 'r') as assetList, open(f2, 'r') as assetListPatch, open(f3, 'r') as assetInfo, open(f4, 'r') as assetInfoPatch:
    assetList_text = assetList.readlines()
    assetListPatch_text = assetListPatch.readlines()
    assetInfo_text = assetInfo.readlines()
    assetInfoPatch_text = assetInfoPatch.readlines()

assetList_text 是一个大(3k+ 行)文件。 所以这里有一些来自assetList_text的信息,包括“.gsc”行:

fx,weapon/shellejects/fx_smk_weapon_shell_eject
fx,weapon/shellejects/fx_smk_weapon_shell_emit
fx,weapon/shellejects/shotgun
fx,weapon/shellejects/shotgun_resting
fx,weapon/shellejects/shotgun_view
fx,weapon/shellejects/shotgun_view_blurred01
mptype,nazi_zombie_heroes
character,char_zomb_player_0
character,char_zomb_player_1
character,char_zomb_player_2
character,char_zomb_player_3
rawfile,animtrees/zombie_factory.atr
rawfile,clientscripts/_zombie_mode.csc
rawfile,clientscripts/createfx/dlc3_fx.csc
rawfile,clientscripts/createfx/free_city_fx.csc
rawfile,clientscripts/dlc3_code.csc
rawfile,clientscripts/dlc3_teleporter.csc
rawfile,clientscripts/free_city.csc
rawfile,clientscripts/free_city_amb.csc
rawfile,maps/createart/free_city_art.gsc
rawfile,maps/createfx/dlc3_fx.gsc
rawfile,maps/createfx/free_city_fx.gsc
rawfile,maps/dlc3_code.gsc
rawfile,maps/dlc3_teleporter.gsc
rawfile,maps/free_city.gsc
rawfile,rumble/flamethrower
rawfile,rumble/flamethrower_h.rmb
rawfile,rumble/flamethrower_l.rmb
rawfile,vision/zombie_factory.vision

尝试将两个 if 语句替换为一个,并添加“and”运算符而不是第二个“if”。 因为我不确定什么 2 'if' 在列表理解中可以正常工作。 所以,改变这个:

gsc_files = [i.split(',')[-1].replace("\n", "") for i in assetList_text if ".gsc" in i if i.split(',')[-1].replace("\n", "") not in gsc_files]

对此:

gsc_files = [i.split(',')[-1].replace("\n", "") for i in assetList_text if (".gsc" in i) and (i.split(',')[-1].replace("\n", "") not in gsc_files)]

'add' 运算符应该比较正确的两个语句

而且我不确定什么尝试转换所有 for 循环或只是列表理解中的大部分代码,这是个好主意,因为这会使您的代码难以阅读

[1] 你提到的第一个 for 循环!

weapon_files = []
x = join(f"{WAW_ROOT_DIR}/raw/weapons/sp")
for path, subdirs, files in walk(x):
    for fileName in files:
    content = join(x, fileName)
    if content not in weapon_files:
        weapon_files.append(f"{WAW_ROOT_DIR}/raw/weapons/sp/{fileName}")

答:希望对你有帮助! 首先,您试图访问在列表理解开始之前未创建的列表。 对于您的情况,您尝试在第一次weapon_files = []处创建一个空列表,列表理解再次创建一个新列表武器文件,但是这一次,我们使用:=运算符将我们需要的数据分配给weapon_files的列表。 请参阅https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions 现在每次递归列表都会根据条件更新。

weapon_files = []
weapon_files = [weapon_files := f"{WAW_ROOT_DIR}/raw/weapons/sp/{fileName}" for path, subdirs, files in walk(x)  for fileName in files if join(x, fileName) not in weapon_files]

[2] 提到了第二个“for 循环”!

gsc_files_dir = []
for path in gsc_files:
if f"{CURRENT_SELECTED_MOD.lower()}" in path:
    #condition 1 ref variable to append ==> var1
    dir = join(f"{WAW_ROOT_DIR}/mods/{CURRENT_SELECTED_MOD}/{path}")
    gsc_files_dir.append(dir)
elif os.path.exists(f"{WAW_ROOT_DIR}/mods/{CURRENT_SELECTED_MOD}/{path}"):
    #condition 2 ref variable to append ==> var2
    dir = join(f"{WAW_ROOT_DIR}/mods/{CURRENT_SELECTED_MOD}/{path}")
    gsc_files_dir.append(dir)
else:
    #condition 3 ref variable to append ==> var3
    dir = join(f"{WAW_ROOT_DIR}/raw/{path}")
    gsc_files_dir.append(dir)

回答:尝试对这个循环语句进行列表推导不会带来更好的可读性,但我们仍然可以应用。 我已经使用上面注释的 ref 变量名称显示了模板答案。(var1,var2,var3)。

gsc_files_dir = [var1 if f"{CURRENT_SELECTED_MOD.lower()}" in path else var2 if os.path.exists(f"{WAW_ROOT_DIR}/mods/{CURRENT_SELECTED_MOD}/{path}") else var3 for path in gsc_files]

暂无
暂无

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

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