简体   繁体   English

检查是否可以使用python中的字符列表创建字符串的最快方法

[英]Fastest way to check if a string can be created with a list of characters in python

I need to check if a string can be created with a list of characters and return True or False. 我需要检查是否可以使用字符列表创建字符串并返回True或False。

I am using different solutions with list.count or collections.Counter. 我正在使用list.count或collections.Counter的不同解决方案。

I am also using this solution which I dont need to read through the list of characters: 我也在使用这个解决方案,我不需要通读字符列表:

def check(message, characters):
    try:
        [list(characters).remove(m) for m in message]
        return True
    except:
        return False

Is there a fastest way? 有最快的方式吗? for a very very very big list of characters. 对于一个非常非常大的角色列表。 Counter and list count seems slower. 计数器和列表计数似乎较慢。 Dont know if there is a fast pythonic way to do this. 不知道是否有快速的pythonic方式来做到这一点。

Example: 例:

message = "hello"
characters = "hheellooasdadsfgfdgfdhgfdlkgkfd"

check(message, characters) # this should return True or False
# characters can be a veeeeery long string

Duplicates matter so for example characters = "hheloo" would not work for message = "hello" 重复事项 ,例如characters =“hheloo”不适用于message =“hello”

You could use collections.Counter() . 您可以使用collections.Counter() Just build two counters and use the subtract() method to check if there're any negative counts: 只需构建两个计数器并使用subtract()方法检查是否有任何负数:

>>> c1 = Counter(characters)
>>> c2 = Counter(message)
>>> c1.subtract(c2)
>>> all(v >= 0 for v in c1.values())
False

This should work in linear time. 这应该在线性时间内起作用。

This is not feasible in linear time, as the length of both strings matter and they need to be iterated for each character. 这在线性时间内是不可行的,因为两个字符串的长度都很重要,并且需要为每个字符迭代它们。 Without having checked its actual implementation, I assume remove() is logarithmic. 在没有检查其实际实现的情况下,我假设remove()是对数的。

def check(msg, chars):
    c = list(chars)  # Creates a copy
    try:
        for m in msg:
            c.remove(m)
    except ValueError:
        return False
    return True

if __name__ == '__main__':
    print(check('hello', 'ehlo'))
    print(check('hello', 'ehlol'))
    print(check('hello', 'ehloijin2oinscubnosinal'))

Here is another solution compared to eugene's solution and jbndlr's solution. 与eugene的解决方案和jbndlr的解决方案相比,这是另一种解决方案。

def test1(input_word, alphabet):
    alp_set = set(list(alphabet))
    in_set = set(list(input_word))
    return in_set.issubset(alp_set)

def test2(input_word, alphabet):
    c1 = collections.Counter(alphabet)
    c2 = collections.Counter(input_word)
    c1.subtract(c2)
    return all(v >= 0 for v in c1.values())

def check(msg, chars):
    c = list(chars)  # Creates a copy
    try:
        for m in msg:
            c.remove(m)
    except ValueError:
        return False
    return True

input_word = "hello"
alphabet = "hheellooasdadsfgfdgfdhgfdlkgkfd"


start_time = time.time()
for i in range(10000):
    test1(input_word,alphabet)
print("--- %s seconds ---" % (time.time() - start_time))

start_time = time.time()
for i in range(10000):
    test2(input_word,alphabet)
print("--- %s seconds ---" % (time.time() - start_time))

start_time = time.time()
   for i in range(10000):
       check(input_word,alphabet)
   print("--- %s seconds ---" % (time.time() - start_time))

>> --- 0.03100299835205078 seconds ---
>> --- 0.24402451515197754 seconds ---
>> --- 0.022002220153808594 seconds ---

⇒ jbndlr's solution is the fastest - for this test case. ⇒jbndlr的解决方案是最快的 - 对于这个测试用例。

Another testcase: 另一个测试用例:

input_word = "hellohellohellohellohellohellohellohellohellohellohellohellohello"
alphabet =   

"" “”

>> --- 0.21964788436889648 seconds ---
>> --- 0.518169641494751 seconds ---
>> --- 1.3148927688598633 seconds ---

⇒ test1 is fastest ⇒test1是最快的

There is maybe a faster way of doing this, apparently due to the cost of creating the all() generator ( Why is Python's 'all' function so slow? ) perhaps a for loop is faster, Expanding on @eugene y's answer: 有一种更快的方法可以做到这一点,显然是由于创建all()生成器的成本( 为什么Python的'all'函数如此慢? )也许for循环更快,扩展@eugene y的答案:

from collections import Counter
import time

message = "hello"
characters = "hheeooasdadsfgfdgfdhgfdlkgkfd"

def check1(message,characters):
    c1 = Counter(characters)
    c2 = Counter(message)
    c1.subtract(c2)
    return all(v > -1 for v in c1.values())

def check2(message,characters):
    c1 = Counter(characters)
    c2 = Counter(message)
    c1.subtract(c2)
    for v in c1.values():
        if v < 0:
            return False
    return True

st = time.time()
for i in range(350000):
    check1(message,characters)
end = time.time()
print ("all(): "+str(end-st))

st = time.time()
for i in range(350000):
    check2(message,characters)
end = time.time()
print ("for loop: "+str(end-st))

results: 结果:

all(): 5.201688051223755
for loop: 4.864434719085693

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

相关问题 Python - 检查字符串是否包含列表中任何项目中的特定字符的最快方法 - Python - Fastest way to check if a string contains specific characters in any of the items in a list 在字符串中交换字符的最快方法(Python) - Fastest way to swap characters in a string (Python) 检查字符串是否包含列表中字符串的最快方法 - Fastest way to check if a string contains a string from a list 检查值或值列表是否是python中列表子集的最快方法 - Fastest way to check if a value or list of values is a subset of a list in python 最快的检查方式是字符串包含列表中的任何单词 - Fastest way to check does string contain any word from list 检查字符串列表中的所有元素是否都在字符串中的最快方法 - fastest way to check if all elements of a list of strings is in a string Python:检查两个字符串列表是否“相似”的最快方法 - Python: fastest way to check whether two string lists are “similar” 检查列表中是否正好有n个项目与python中的条件匹配的最快方法 - Fastest way to check if exactly n items in a list match a condition in python 检查python列表/numpy ndarray中是否存在重复项的最快方法 - Fastest way to check if duplicates exist in a python list / numpy ndarray 在字符串列表列表中编码字符的最快方法 - Fastest way to encode characters in a list of list of strings
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM