Python中除了写循环还有什么更好的替代方法?
要验证 b 是否在 a 中,除了写循环还有什么更好的办法?
a = array([False, False, False, True, True, True, False, False, False, False, False, False])
b = array([True, True, True])
i = 0
while True:
if np.all(b == a[i:i+3]) == True:
print(‘match’)
break
i += 1
else:
print(‘no match’)
Python中除了写循环还有什么更好的替代方法?
Python里替代循环的方法很多,核心思路是用向量化操作和内置的高阶函数。
1. 列表推导式(List Comprehension)
代替简单的 for 循环生成列表:
# 传统循环
squares = []
for i in range(10):
squares.append(i**2)
# 列表推导式
squares = [i**2 for i in range(10)]
2. map() 和 filter()
map() 对可迭代对象应用函数,filter() 按条件过滤:
nums = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, nums))
evens = list(filter(lambda x: x % 2 == 0, nums))
3. 使用 itertools 模块
处理迭代任务,比如组合、排列、无限迭代器等:
import itertools
# 组合
for combo in itertools.combinations([1, 2, 3], 2):
print(combo)
4. NumPy 向量化运算(适合数值计算)
用 NumPy 数组代替循环进行批量计算:
import numpy as np
arr = np.array([1, 2, 3, 4])
result = arr * 2 # 直接对整个数组操作,无需循环
5. Pandas 的 apply() 和向量化操作
在数据处理时避免显式循环:
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3]})
df['B'] = df['A'].apply(lambda x: x**2) # 按列应用函数
# 或者直接向量化运算
df['C'] = df['A'] * 2
6. 使用内置的 sum()、any()、all() 等聚合函数
这些函数底层用 C 实现,效率比手写循环高:
nums = [1, 2, 3, 4]
total = sum(nums) # 代替累加循环
has_negative = any(n < 0 for n in nums) # 代替条件判断循环
总结建议:根据场景选择合适的方法,向量化操作通常最快。
[x in a for x in b]
这不就是 KMP 吗?
你写的这个东西和楼主想实现的功能有任何关系么…
>>> a = [0, 1]
>>> b = [1, 1, 1, 1, 1]
>>> [x in a for x in b]
[True, True, True, True, True]
>>> from numpy import *
>>> a = array([False, False, False, True, True, True, False, False, False, False, False, False])
>>> b = array([True, True, True])
>>> [ i for i in b if i not in a ]
[]
>>> b = array([True, True, 123])
>>> [ i for i in b if i not in a ]
[123]
空集为真,非空集为假
本质上还是循环,算法复杂度是没变的。
如果你的需求是求解集合子集,那不允许出现重复元素,直接转换成 set,用 in 判断是否子集
如果你的需求中包含了元素顺序,那就比较困难了。
他写反了
只能拿 b 的第一个去 a 里找,找对了找 b 的下一个是不是 a 的下一个,直到 b 的结尾都匹配,则 b 在 a 中
除了循环还能有什么办法
先引入 rolling_window: https://gist.github.com/seberg/3866040
然后
import numpy as np
a = np.array([False, False, False, True, True, True, False, False, False, False, False, False])
b = np.array([True, True, True])
l = b.shape[0]
needle = np.equal(rolling_window(a, l), b)
is_matched = np.max(np.sum(needle, axis=-1)) == l
另外题主,b == a[i:i+3] 这种写法已经 deprecated 了,要用 np.equal
我来偷个懒:
a = bytes([False, False, False, True, True, True, False, False, False, False, False, False])
b = bytes([True, True, True])
match = a.find(b) >= 0
print(match)
那就递归吧
显然需求里包含了元素顺序,不然一共就 True 和 False 两种有啥好判断的
这个我知道,只是不想用纯 Python 写循环,又找不到 numpy 有什么函数可用。
你的需求决定了你的算法只能是循环决定,难道有现成的 numpy 函数它运行的时候就不需要循环了吗?
他自己写那段代码就没包含。
你的意思如果是要打印出每一个 True False 的话那就用[x in b for x in a]
不点评我那个实现吗
我那个实现就不用循环
谢谢,你那个有点复杂,一时看不懂,不好意思。
我想到的是’’.join(map(str, b)) in ‘’.join(map(str, a))
看了下评论,为什么说 1 楼的代码是错的?
false 为 0
True 为 1
bool 数组转换为整型数之后,判断以 b 为模余数是否为 0
就可以了
楼上这这些人,你们怎么一根筋不知道变通?<br>import numpy as np<br><br>a = np.array([False, False, False, True, True, True, False, False, False, False, False, False]) <br>b = np.array([True, True, True]) <br>if str(b)[1:-1] in str(a):<br> print('b 在 a 中')<br>
哈哈哈,这操作很骚…
用字符串匹配喽
吓得我赶紧去翻了一下编译原理,这就是最简单的有穷自动机呀。
Map reduce filter
sets.difference()
如果不是 bool,这招就不管用了
楼上说了,用 kmp 可以实现
不就是最长公共子序列吗
老哥这些 gist 里的注释和 doc test 都是你手写的么?
大胸弟你这样会被打死的
这个 gist 不是我写的,是我见过的写得最好的 rolling_window。
我昨天写的 np.max 其实还不太妥当。用 np.any 其实就够了:
is_matched = np.any(np.equal(np.sum(needle, axis=-1), l).astype(np.bool))
也管用。
浮点数的话,要用 (a-b) < eps,就用不了你这方法了。
上面的 astype(np.bool) 似乎不必要。
转 set b-a
谢谢各位热心的 v2exer。

