我已经检查过以下答案: Replacements for switch statement in Python? 和 How to refactor Python "switch statement"
但我认为两者都是指单个案例的简单switch语句。
我遇到的问题是switch语句看起来像这样:
switch(view) {
case "negatives":
label = 0;
break;
case "cars\\00inclination_000azimuth":
case "buses\\00inclination_000azimuth":
case "trucks\\00inclination_000azimuth":
label = 1;
break;
case "cars\\00inclination_045azimuth":
case "buses\\00inclination_045azimuth":
case "trucks\\00inclination_045azimuth":
case "cars\\00inclination_090azimuth":
case "buses\\00inclination_090azimuth":
case "trucks\\00inclination_090zimuth":
case "cars\\00inclination_135azimuth":
case "buses\\00inclination_135azimuth":
case "trucks\\00inclination_135azimuth":
label = 2;
break;
# and so on
因此,有很多情况会导致相同的标签。有没有快速的方法来使用列表?我可以在哪里使用这样的东西
a = ["cars\\00inclination_045azimuth","buses\\00inclination_045azimuth","trucks\\00inclination_045azimuth","cars\\00inclination_090azimuth","buses\\00inclination_090azimuth", "trucks\\00inclination_090zimuth","cars\\00inclination_135azimuth","buses\\00inclination_135azimuth","trucks\\00inclination_135azimuth"]
if view in a:
label = 2
但是,我必须为映射到同一标签的每组案例制作一个列表,然后通过每个案例。
有没有办法执行以下操作,如果没有,那么最简单的方法是什么?
if view in _any_of_the_lists_i've_made:
label = the_index_of_that_list
我在问题中显示的值只是少数,以便对问题有一个大概的了解。但我从一些评论中意识到,最好给出我所拥有的全部价值观作为案例。
总的来说,每辆车有25个视图,有3辆车,有75种不同的视图,即75个。
答案 0 :(得分:3)
您的视图字符串遵循一种模式;它们由<transport>\<inclination>_<azimuth>
组成,并且您的标签仅在方位角值上有所不同。
将字符串简化为方位角值,然后使用dict
找到您的标签:
labels = {'000': 1, '045': 2, '090': 2, '135': 2}
label = 0 if view == 'negatives' else labels[view.rpartition('_')[-1][:3]]
这会从azimuth
字符串中取出 3位数。
为了说明这是如何工作的,一个简短的演示:
>>> "cars\\00inclination_000azimuth".rpartition('_')
('cars\\00inclination', '_', '000azimuth')
>>> "cars\\00inclination_000azimuth".rpartition('_')[-1]
'000azimuth'
>>> "cars\\00inclination_000azimuth".rpartition('_')[-1][:3]
'000'
str.rpartition()
分割最后一个_
字符,我们从中选择最后一个元素,然后从最后一个元素中分割前3个字符。
如果你也需要改变倾向,那就解析一下:
labels = {
None: 0,
('00', '000'): 1,
('00', '045'): 2,
('00', '090'): 2,
('00', '135'): 2,
# etc.
}
if view == 'negatives':
key = None
else:
key = view.partition('\\')[-1][:2], view.rpartition('_')[-1][:3]
label = labels[key]
通过将视图缩小到只有那些重要的部分,您可以大大减少字典的大小,或者至少您需要输入的部分。
当然,直接查看视图字符串会更快。您始终可以生成上述字典中的完整字符串:
for key, label in labels.items():
if key is None:
labels['negatives'] = label
continue
for vehicle in ('cars', 'trucks', 'buses'):
labels['{}\\{}inclination_{}azimuth'.format(vehicle, *key)] = label
然后直接查找您的标签:
label = labels[view]
答案 1 :(得分:0)
正如一些评论者指出的那样,您最好的解决方案是更充分地解析字符串,并获取其中的关键信息,这将减少您的案例。如果由于某种原因你不能,你可以这样做:
CASES = [
{
"negatives",
},
{
"cars\\00inclination_000azimuth",
"buses\\00inclination_000azimuth",
"trucks\\00inclination_000azimuth",
},
{
"cars\\00inclination_045azimuth",
"buses\\00inclination_045azimuth",
"trucks\\00inclination_045azimuth",
"cars\\00inclination_090azimuth",
"buses\\00inclination_090azimuth",
"trucks\\00inclination_090zimuth",
"cars\\00inclination_135azimuth",
"buses\\00inclination_135azimuth",
"trucks\\00inclination_135azimuth",
},
]
def find_label(view):
for label, views in enumerate(CASES):
if view in views:
return label
请注意,我已使用集来加速view in views
检查。
更好的是,您可以将您的集合列表预处理为单个字典:
CASE_DICT = { view:label for label, views in enumerate(CASES) for view in views }
def find_label(view):
return CASE_DICT.get(view, None)
答案 2 :(得分:0)
这里的其他答案都很好,但是基于dict的查找表没有任何问题 - 如果你打算经常访问它,一个更大的dict比预处理字符串更快,以便在每次查找时提取值。
def get_label(val):
label_map = {
"negatives": 0,
"cars\\00inclination_000azimuth": 1,
"buses\\00inclination_000azimuth": 1,
"trucks\\00inclination_000azimuth": 1,
"cars\\00inclination_045azimuth": 2,
(...etc...)
}
return label_map[val]
答案 3 :(得分:0)
由于车辆的映射存在巨大的重叠:倾角:方位角值,您可以使用intertools product将重叠字符串的元组描述为映射。
假设您可以将label
描述为'2'
,其中车辆为['cars', 'buses', 'trucks']
中的任何一个,方位角为['0']
中的任意一个且倾角为{{1}中的任意一个你的例子说的是什么。
你可以这样做:
['45', '90', '135']
然后很容易添加添加&#39;案例&#39;使用.update,product和dict comprehension的值(借用C的意义):
from itertools import product
vehicles=['cars', 'buses', 'trucks']
switch={}
switch.update({t:2 for t in product(vehicles, ['0'], ['45', '90', '135'])})
print switch
# {('buses', '0', '90'): 2, ('buses', '0', '45'): 2, ('cars', '0', '135'): 2, ('trucks', '0', '135'): 2, ('trucks', '0', '90'): 2, ('cars', '0', '45'): 2, ('trucks', '0', '45'): 2, ('cars', '0', '90'): 2, ('buses', '0', '135'): 2}
重复每个可描述的车辆组合:倾角:方位角值。
然后,您可以直接从感兴趣的值的元组的键值分配标签:
>>> switch.update({t:1 for t in product(vehicles, ['0'], ['0'])})
>>> switch
{('buses', '0', '90'): 2, ('buses', '0', '45'): 2, ('cars', '0', '135'): 2, ('trucks', '0', '135'): 2, ('trucks', '0', '90'): 2, ('cars', '0', '45'): 2, ('trucks', '0', '45'): 2, ('cars', '0', '90'): 2, ('buses', '0', '135'): 2, ('cars', '0', '0'): 1, ('buses', '0', '0'): 1, ('trucks', '0', '0'): 1}
无需全部输入。
您还可以使用>>> label=switch[('cars', '0', '0')]
>>> label
1
来设置默认值:
.get()