用 python3 中的特定元素替换元素组
Replace elements group with a particular element in python3
我有一个包含 50 多个元素的列表。这些元素是大小写字母、数字、特殊字符。
例如
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
我想交换具有特殊字符的特定元素。
例如。
replacing `A,B,C and 1 with @
replacing `D,E,F and 2 with &
replacing `G,H,I and 3 with (
等等,我必须用 11 个选定的特殊字符替换一组特定的元素。就像我用 3 个特殊字符替换了几个选定的元素。
如何有效地做到这一点。
您首先需要定义您的替换规则,例如 dict
。特别是,由于 dict
允许 O(1) 访问,这与您的方法能够获得时间复杂度的速度一样快:即在单次遍历list.
然后您可以遍历列表并替换每个元素,如果它有替换规则。
rules = {
'A': '@',
'B': '@',
'D': '&',
'E': '&'
}
for i, c in enumerate(sample_list):
if c in rules:
sample_list[i] = rules[c]
如果你想创建一个新列表而不是改变初始列表,你可以使用列表理解
new_list = [rules.get(c, c) for c in sample_list]
例子
rules = {
'A': '@',
'B': '@',
'D': '&',
'E': '&'
}
sample_list = ['A', 'A', 'B', 'C', 'D', 'E', 'F']
new_list = [rules.get(c, c) for c in sample_list]
print(new_list)
输出
['@', '@', '@', 'C', '&', '&', 'F']
您可以使用 translate
方法按照以下方式完成:
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
t = ''.maketrans('ABC1DEF2GHI3','@@@@&&&&((((')
out = [i.translate(t) for i in sample_list]
print(out)
输出:
['@', '0', 'b', '@', '&', '6', 'a', '7', '9', '5', 'c', 'd', '4', '@', '@', 'f', '&', '&', '(', '@', '8', '@', '&', '@', '@', '@', '&']
maketrans
str
的方法用于创建翻译 table,只需为其提供两个等长的 str
s,第一个由键组成,第二个由值组成. translate
方法接受 table 并相应地替换字符,如果 table.
中没有这样的键,则保持原样不变
编辑:正如 Olivier Melançon 所指出的,只有当您想用 1 个字符替换 1 个字符时才能使用它。
试试这个并在字典中设置所有映射:
chars = {"@": ["A", "B", "C", "1"], "&": ["D", "E", "F", "2"]}
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
for k, v in chars.items():
for value in v:
if value in sample_list:
ind = [index for index, val in enumerate(sample_list) if val == value]
for x in ind:
sample_list[x] = k
print(sample_list)
可以使用地图功能:
Ex 第一次替换:
new_list = map(lambda x: '@' if x in ('A', 'B', 'C') else x, sample_list)
sample_list 也可以是一个字符串(每个字符都是一个元素,但是 map 将 return 无论如何都是一个数组)。
在 "string" 列表中,您可以只使用替换方法:
compact_list = ''.join(sample_list)
new_compact_list = compact_list.replace('A', '@').replace('B', '@').replace('C', '@')
当然如果源列表是可变的,围绕它写一个循环...
从一个简单的功能开始,然后对其进行完善。
简单的是使用 3 sets
(因为查找集比列表更好)- 如果集不需要变异,请改用 frozensets
。使用简单的循环 - 直接:
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
new_list = []
for item in sample_list:
abc = frozenset("ABC") # frozensets do not change, they are immuteable
dfe = frozenset("DEF") # and fast for lookups. this is less performant
ghi = frozenset("GHI") # then using a dict - but it works as well
if item in abc:
new_list.append("@")
elif item in dfe:
new_list.append("&")
elif item in ghi:
new_list.append("(")
else:
new_list.append(item)
print(new_list)
输出:
['1', '0', 'b', '@', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', '@', '@', 'f', '&', '&', '3', '@', '8', '@', '&', '@', '@', '@', '&']
为了更花哨,请使用字典和 list-comp:
transform = {"A":"@", "B":"@", "C":"@",
"D":"&", "E":"&", "F":"&",
"G":"(", "H":"(", "I":"("}
new_list = [ transform.get(i,i) for i in sample_list]
输出:
['1', '0', 'b', '@', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', '@', '@', 'f', '&', '&', '3', '@', '8', '@', '&', '@', '@', '@', '&']
参见:
- set()/frozenset()
- list comprehensions
- Why dict.get(key) instead of dict[key]?
我有一个包含 50 多个元素的列表。这些元素是大小写字母、数字、特殊字符。
例如
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
我想交换具有特殊字符的特定元素。 例如。
replacing `A,B,C and 1 with @
replacing `D,E,F and 2 with &
replacing `G,H,I and 3 with (
等等,我必须用 11 个选定的特殊字符替换一组特定的元素。就像我用 3 个特殊字符替换了几个选定的元素。
如何有效地做到这一点。
您首先需要定义您的替换规则,例如 dict
。特别是,由于 dict
允许 O(1) 访问,这与您的方法能够获得时间复杂度的速度一样快:即在单次遍历list.
然后您可以遍历列表并替换每个元素,如果它有替换规则。
rules = {
'A': '@',
'B': '@',
'D': '&',
'E': '&'
}
for i, c in enumerate(sample_list):
if c in rules:
sample_list[i] = rules[c]
如果你想创建一个新列表而不是改变初始列表,你可以使用列表理解
new_list = [rules.get(c, c) for c in sample_list]
例子
rules = {
'A': '@',
'B': '@',
'D': '&',
'E': '&'
}
sample_list = ['A', 'A', 'B', 'C', 'D', 'E', 'F']
new_list = [rules.get(c, c) for c in sample_list]
print(new_list)
输出
['@', '@', '@', 'C', '&', '&', 'F']
您可以使用 translate
方法按照以下方式完成:
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
t = ''.maketrans('ABC1DEF2GHI3','@@@@&&&&((((')
out = [i.translate(t) for i in sample_list]
print(out)
输出:
['@', '0', 'b', '@', '&', '6', 'a', '7', '9', '5', 'c', 'd', '4', '@', '@', 'f', '&', '&', '(', '@', '8', '@', '&', '@', '@', '@', '&']
maketrans
str
的方法用于创建翻译 table,只需为其提供两个等长的 str
s,第一个由键组成,第二个由值组成. translate
方法接受 table 并相应地替换字符,如果 table.
编辑:正如 Olivier Melançon 所指出的,只有当您想用 1 个字符替换 1 个字符时才能使用它。
试试这个并在字典中设置所有映射:
chars = {"@": ["A", "B", "C", "1"], "&": ["D", "E", "F", "2"]}
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
for k, v in chars.items():
for value in v:
if value in sample_list:
ind = [index for index, val in enumerate(sample_list) if val == value]
for x in ind:
sample_list[x] = k
print(sample_list)
可以使用地图功能:
Ex 第一次替换:
new_list = map(lambda x: '@' if x in ('A', 'B', 'C') else x, sample_list)
sample_list 也可以是一个字符串(每个字符都是一个元素,但是 map 将 return 无论如何都是一个数组)。
在 "string" 列表中,您可以只使用替换方法:
compact_list = ''.join(sample_list)
new_compact_list = compact_list.replace('A', '@').replace('B', '@').replace('C', '@')
当然如果源列表是可变的,围绕它写一个循环...
从一个简单的功能开始,然后对其进行完善。
简单的是使用 3 sets
(因为查找集比列表更好)- 如果集不需要变异,请改用 frozensets
。使用简单的循环 - 直接:
sample_list = ['1', '0', 'b', 'B', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', 'A', 'C', 'f', 'D', 'F', '3', 'C', '8', 'A', 'F', 'B', 'A', 'A', 'D']
new_list = []
for item in sample_list:
abc = frozenset("ABC") # frozensets do not change, they are immuteable
dfe = frozenset("DEF") # and fast for lookups. this is less performant
ghi = frozenset("GHI") # then using a dict - but it works as well
if item in abc:
new_list.append("@")
elif item in dfe:
new_list.append("&")
elif item in ghi:
new_list.append("(")
else:
new_list.append(item)
print(new_list)
输出:
['1', '0', 'b', '@', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', '@', '@', 'f', '&', '&', '3', '@', '8', '@', '&', '@', '@', '@', '&']
为了更花哨,请使用字典和 list-comp:
transform = {"A":"@", "B":"@", "C":"@",
"D":"&", "E":"&", "F":"&",
"G":"(", "H":"(", "I":"("}
new_list = [ transform.get(i,i) for i in sample_list]
输出:
['1', '0', 'b', '@', '2', '6', 'a', '7', '9', '5', 'c', 'd', '4', '@', '@', 'f', '&', '&', '3', '@', '8', '@', '&', '@', '@', '@', '&']
参见:
- set()/frozenset()
- list comprehensions
- Why dict.get(key) instead of dict[key]?