【问题标题】:Function works for small samples but not larger ones (Python)函数适用于小样本但不适用于大样本(Python)
【发布时间】:2021-12-12 04:05:00
【问题描述】:

我正在尝试制作一个函数来查看单词是否出现在彼此之间的一定距离内,我的代码如下:



file_cont = [['man', 'once', 'upon', 'time', 'love', 
'princess'], ['python', 'code', 'cool', 'uses', 'java'],
['man', 'help', 'test', 'weird', 'love']] #words I want to measure 'distance' between

dat = [{ind: val for val, ind in enumerate(el)} for el in file_cont]

def myfunc(w1, w2, dist, dat):
    arr = []
    for x in dat:
        i1 = x.get(w1)
        i2 = x.get(w2)
        if (i1 is not None) and (i2 is not None) and (i2 - i1 <= dist ):    
            arr.append(list(x.keys())[i1:i2+1])
    return arr

在这种情况下有效,

myfunc("man", "love",4, dat) 返回 [['man', 'once', 'on', 'time', 'love'] , ['man', 'help', 'test', 'weird', 'love']] 这就是我想要的

我遇到的问题是,当我使用更大的数据集(file_cont 的元素变成数千个单词)时,它会输出奇怪的结果

例如,我知道“jon”和“snow”这两个词至少一起出现在 file_cont 的元素之一中

当我这样做 myfunc('jon','snow',6,dat) 我得到:

[[], [], ['城堡', '病房'], [], [], []]

完全断章取义,没有提到“jon”或“snow”

这里有什么问题,我将如何解决它?

【问题讨论】:

  • 我想到了两件事:首先,您提到问题仅在使用更大的数据集时才会出现。你是如何使用这个数据集的?您是否正在阅读文本文件并将其拆分为列表?问题可能是由您读取数据的方式引起的。否则,您提到"jon" 和"snow" 的情况。也许您应该确保以不区分大小写的方式搜索单词,例如使用s.lower() 其中s 是一个字符串?
  • @bglbrt 我已经把单词小写了,但仍然有同样的问题
  • @bglbrt 它也是来自 [['string1', 'string2'], ['string3', 'string4', 'string5']] 的相同数据,只是更长
  • 我添加了一个进一步调查问题的答案,我认为这是因为您的新数据可能多次出现相同的单词。
  • @bglbrt 该代码适用于较长的大型列表,但似乎仍不适用于长列表,即 [ [ 'word1',....., 'word1000'] , [ 'word3', ...... 'word5000'], ['word4', .... 'word400']] 即使我想找到之间距离的单词在同一个列表中(这就是我我的目标)

标签: python arrays function memory-management nlp


【解决方案1】:

问题在于您的文本可能包含多次出现的同一个单词,您通常会在较大的摘录中观察到这种情况。

这是一个最小的工作示例,展示了函数可能会如何失败:

new_file = [['man', 'once', 'man', 'time', 'love', 'once']]
data = [{ind: val for val, ind in enumerate(el)} for el in new_file]

def myfunc(w1, w2, dist, dat):
    arr = []
    for x in dat:
        i1 = x.get(w1)
        i2 = x.get(w2)
        if (i1 is not None) and (i2 is not None) and (i2 - i1 <= dist ):    
            arr.append(list(x.keys())[i1:i2+1])
    return arr

myfunc("man", "love", 4, data)
# > [['time', 'love']]

请注意,您的字典将如下所示:

# > [{'man': 2, 'once': 5, 'time': 3, 'love': 4}]

这是因为,在创建字典时,每个新出现的单词都会用新观察到的(更高的)索引替换其在字典中的键。因此,函数myfunc 失败,因为字典中的键不再对应于摘录中单词的索引。


实现您想要做的事情的方法可能是(例如):

data = ['man', 'once', 'upon', 'man', 'time', 'love', 'princess', 'man']
w1 = 'man'
w2 = 'love'
dist = 3

def new_func(w1, w2, dist, data):

    w1_indices = [i for i, x in enumerate(data) if x == w1]
    w2_indices = [i for i, x in enumerate(data) if x == w2]

    for i in w1_indices:
        for j in w2_indices:
            if abs(i-j) < dist:
                print(data[min(i, j):max(i, j)+1])
                
new_func(w1, w2, dist, data)
# > ['man', 'time', 'love']
# > ['love', 'princess', 'man']

使用您的情况下的列表列表,您可以执行以下操作:

file_cont = [['man', 'once', 'upon', 'time', 'love', 'princess'], ['python', 'code', 'cool', 'uses', 'java'],
['man', 'help', 'test', 'weird', 'love']]

results = [new_func(w1, w2, dist, x) for x in file_cont]
print(results)
# > ['man', 'once', 'upon', 'time', 'love']
# > ['man', 'help', 'test', 'weird', 'love']

【讨论】:

  • 我相信你的代码有错误:print(a[min(i, j):max(i, j)+1]),这应该是abs吗?
  • 你说得对——我更正了,应该是print(data[min(i, j):max(i, j)+1])。
猜你喜欢
  • 2022-01-11
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 2021-07-30
  • 1970-01-01
相关资源
最近更新 更多