微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么这个 List Comprehension 不会产生与这个 for/in 循环相同的结果?

如何解决为什么这个 List Comprehension 不会产生与这个 for/in 循环相同的结果?

生成一个随机字符串列表,然后使用 for/in 循环和列表理解表达式来资助最长的字符串和该字符串的长度。

这两种技术都能正确计算最大长度,但有时 for/in 循环会找到与 List Comprehension 相同的最长单词,有时则不会。为什么?什么逻辑错误

import random
import string
def cobble_large_dataset(dataset_number_of_elements):
    '''
    Build a list of Lists,each List is a String of a random sequence of 1-10 characters
    '''
    myList = []         # Empty List   
    for i in range(0,dataset_number_of_elements):
        string_length = random.randint(1,10)
        tmp = ''.join(random.choices(string.ascii_uppercase + string.digits,k=string_length))  # https://stackoverflow.com/questions/2257441/random-string-generation-with-upper-case-letters-and-digits
        tmp = [tmp]
        #print(tmp)
        myList.extend([tmp])
    return myList    

def list_comprehension_test(wordsList):
    '''
    Process a List of Lists using List Comprehension. 
    Each List in the List of Lists is a single String
    '''
    start_time = time.time()
   
    maximumWordLength,longest_word = max([(len(x[0]),x[0]) for x in wordsList]) # This works because x is a List of strings
    return ((time.time() - start_time),longest_word,maximumWordLength)

def brute_force_test(wordsList):
    '''
    Process a List of Lists using a brute-force for/in loop. 
    Each List in the List of Lists is a single String    
    '''
    start_time = time.time()
    maximumWordLength = 0
    for word in wordsList:
        tmp = word[0]
        #print(tmp)
        if (len(tmp) >= maximumWordLength):
            maximumWordLength = len(tmp)
            longest_word = tmp
            #print(tmp)
            #print(longest_word + " : " + str(maximumWordLength))
    return ((time.time() - start_time),maximumWordLength)

import time
start_time = time.time()
dataset = cobble_large_dataset(100)
print (str(len(dataset)) + ' Strings generated in ' + str((time.time() - start_time)) + ' seconds.')

# Let's see if both techniques produce the same results:
result_brute_force = brute_force_test(dataset)
print('Results from Brute Force = ' + result_brute_force[1] + ',' + str(result_brute_force[2]) + ' characters' )
result_list_comprehension = list_comprehension_test(dataset)
print('Results from List Comprehension = ' + result_list_comprehension[1] + ',' + str(result_list_comprehension[2]) + ' characters' )
if (result_list_comprehension[1] == result_brute_force[1]):
    print("Techniques produced the same results.")
else:
    print("Techniques DID NOT PRODUCE the same results

解决方法

您将元组列表传递给 max,没有 key 函数,因此 max 正在比较元组,而不仅仅是长度。当长度相同时,元组比较继续比较第二个元素,即字符串本身,因此长度相同的情况下的最大值是比较最大的字符串(通过字典代码点比较)。

相反,在长度相同的情况下,您的循环选择最后出现的候选者。 (如果您在 > 中使用 >= 而不是 if (len(tmp) >= maximumWordLength):,它会选择第一个候选人。)

(此外,您正在使用 tmp 做一些奇怪的事情。您正在构建的 1 元素列表毫无意义 - cobble_large_dataset 应该只返回一个简单的字符串列表。)>

,

在您的列表推导式情况下,您想告诉 max 只对列表中每对值中的第一项进行操作。这相当于 for 循环的情况,因为它只考虑每个字符串的长度。所以你想要:

maximumWordLength,longest_word = max(
    [(len(x[0]),x[0]) for x in wordsList],key = lambda x: x[0])  # This works because x is a List of strings

正如其他人已经指出的那样,您还想将蛮力情况下的 >= 比较更改为 >。如果您进行这两项更改,则您的两种方法将获得相同的结果。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。