Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3+;是否可以使用交换机更换if in和elif in_Python_Python 3.x_Dictionary_If Statement_Switchers - Fatal编程技术网

Python 3+;是否可以使用交换机更换if in和elif in

Python 3+;是否可以使用交换机更换if in和elif in,python,python-3.x,dictionary,if-statement,switchers,Python,Python 3.x,Dictionary,If Statement,Switchers,我知道如何使用字典作为Python中的切换器。我不知道如何使用我的具体情况之一。我想我只需要使用if、elif和else,但希望社区证明我错了:) 我想为字符串中的某些字符创建一个查找/替换函数。字符串至少是一个句子,但通常更多,由许多单词组成 基本上,我所做的是: if non-breaking hyphen in string: # string is a sentence with many words replace non-breaking hyphen with dash e

我知道如何使用字典作为Python中的切换器。我不知道如何使用我的具体情况之一。我想我只需要使用if、elif和else,但希望社区证明我错了:)

我想为字符串中的某些字符创建一个查找/替换函数。字符串至少是一个句子,但通常更多,由许多单词组成

基本上,我所做的是:

if non-breaking hyphen in string:  # string is a sentence with many words
  replace non-breaking hyphen with dash

elif en dash in string:
  replace en dash with dash

elif em dash in string:
  replace em dash with dash

elif non-breaking space in string:
  replace non-breaking space with space
。。。。诸如此类

我能想到的唯一一件事是将字符串拆分成单独的子字符串,然后循环遍历它们,然后字典切换器就可以工作了。但这显然会增加很多额外的处理时间,使用字典切换器的目的是节省时间

我到处都找不到关于这个特定主题的任何东西

有没有办法在Python中使用if-in和elif-in来使用切换器?

下面是解决方案


请注意,这仅在您希望替换输入中的单个字符时有效
{'a':'bb'}
是一个有效的
替代品
,但
{'bb':'a'}
不是。

尽管本杰明的答案可能是正确的,但它是针对具体情况的,而你的问题具有相当普遍的语气。有一种通用的函数方法(我添加了Python3.5类型注释,使此代码具有自解释性):


在您的例子中,这是非常多余的,因为您的示例归结为一个正则表达式操作。请注意,虽然
开关可以是任意iterable,但您可能希望使用具有可预测迭代顺序的东西,即任意
序列
类型(例如
列表
元组
),因为将使用具有匹配谓词的第一个操作。

只是为了表明regex是一个有效的解决方案,以及一些计时:

replacements = {
    '\u2011': '-',
    '\u2013': '-',
    '\u2014': '-',
    '\u00A0': ' ', 
}

import re
s = "1‑‑‑‑2–––––––3————————"

re.sub(
    '|'.join(re.escape(x) for x in replacements),
    lambda x: replacements[x.group()], s
)
# Result
1----2-------3--------
计时
str.trans
获胜,而且更干净)


在我看来,正则表达式非常适合。每个
if
子句使用一个正则表达式,您不需要任何条件逻辑。@cxw如果每个
if
子句需要一个正则表达式,使用正则表达式代替字符串操作有什么意义?您只需要
if
语句,而不是
elif
。如果
字符串
中有一个
en破折号
,这并不意味着您也要忽略字符串中的
em破折号
,是吗?如果您要替换的每件东西都是一个字符,那么您应该首先使用
If
s,但这真的有必要吗?为什么不在不先检查角色是否存在的情况下执行替换<代码>如果s:s=s.replace(“.”,“-”)中的“.”与
s=s.replace(“.”,“-”)本身具有相同的行为。@Kevin谢谢,我将改变这一点,因为我所做的是多余的。为了解决这个问题,我们假设我没有替换文本,也没有根据字符串中的内容执行其他操作,是否可以创建字典切换器?我在这里看到的问题是,您将立即替换所有内容,与伪代码实现相反OP@BenjaminToueg我给人的印象是,这是他们真正想要的,即使这不是他们写的。@Patrick Haugh抱歉,我没有你想要的那么清楚。这很难在课文中解释。这就是我想要的,谢谢。这种方法的主要优点是它可以处理多个字符子字符串,您可能需要替换这些字符子字符串。我建议使用
'|'.join(替换中x的转义(x)
),以避免在存在要替换的正则表达式相关字符时出现任何问题(并且无需调用
键()
)。我不确定
'({}).format(…)
部分是否必要,您可以直接使用
join
调用中的
x | y
作为模式,因为替换工作根本没有捕获组。是的,正在清理正则表达式,感谢您的建议,我将更新good解决方案,但无法读取。如果你添加了一个用法示例,这样人们就可以知道如何使用它,那会有很大帮助。@Aran Fey我对添加一个示例犹豫不决,因为在OP的示例中,这个解决方案是多余的。不过,给你。是的,写一堆lambda是很烦人的。它可能作为配方比函数更有用。使用lambda内联的循环会看起来更干净。@Aran Fey一般来说,使用函数的目的是能够将其部分应用于开关列表(例如,
replace\u dashes=partial(开关,开关)
或者甚至
partial(开关,开关,默认)
,如果默认值也是固定的)并在不同的位置/表达式中多次重复使用切换器,以实现表达性(在函数编程意义上)代码。
from typing import TypeVar, Callable, Iterable

A = TypeVar('A')
B = TypeVar('B')
Predicate = Callable[[A], bool]
Action = Callable[[A], B]
Switch = Tuple[Predicate, Action]

def switch(switches: Iterable[Switch], default: B, x: A) -> B:
    return next(
        (act(x) for pred, act in switches if pred(x)), default
    )

switches = [
    (lambda x: '\u2011' in x, lambda x: x.replace('\u2011', '-')),
    (lambda x: '\u2013' in x, lambda x: x.replace('\u2013', '-'))
]
a = "I'm–a–string–with–en–dashes"

switch(switches, a, a) # if no switches are matched, return the input
replacements = {
    '\u2011': '-',
    '\u2013': '-',
    '\u2014': '-',
    '\u00A0': ' ', 
}

import re
s = "1‑‑‑‑2–––––––3————————"

re.sub(
    '|'.join(re.escape(x) for x in replacements),
    lambda x: replacements[x.group()], s
)
# Result
1----2-------3--------
s = "1‑‑‑‑2–––––––3————————"
s *= 10000

%timeit re.sub('|'.join(re.escape(x) for x in replacements), lambda x: replacements[x.group()], s)
90.7 ms ± 182 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [733]: %timeit s.translate(trans)
15.8 ms ± 59.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)