将单词与最近的索引组合

时间:2015-09-25 09:37:37

标签: python python-3.x

我在两种语言的上下文中都有一个带有索引的术语文件,格式为

1. (2- human rights, 10- workers rights)>> (3- droits de l'homme, 7- droit des travailleurs)
2. (2- human rights, 10- workers rights, 19- women rights)>> (5- droits de l'homme, 15- les droits des femmes)

目标是将第一语言(英语)中的每个单词附加到另一种语言(法语)中句子中最接近的单词,因此输出将为

 human rights : droits de l'homme
 workers rights : droit des travailleurs
 human rights : droits de l'homme
 women rights  : les droits des femmes

这是评论:人权> droits de l'homme:因为n.2(英语句子中“人权”的位置)接近n.3(法语句子中“droits de l'homme”的位置),与其他数字相比较法国名单(在这种情况下为n.7);并以同样的方式“工人权利”>“droit des travailleurs”

人权> droits de l'homme:因为n.2(英语句子中“人权”的位置)接近n.5(法语句子中“droits de l'homme”的位置),与其他数字相比较法国名单(在这种情况下为15);并以同样的方式“妇女权利”> “les droits des femmes”:因为n.19接近n.15(与n.10相比)

有人可以通过相同的方式获得此输出吗?

1 个答案:

答案 0 :(得分:2)

不完整但应该让你入门:

from bisect import bisect
import re

with open("test.txt") as f:
    r = re.compile("(\d+)")
    for line in f:
        a, b = line.lstrip("0123456789. ").split(">> ")
        a_keys = [int(i.group()) for i in r.finditer(a)]
        b_keys =  [int(i.group()) for i in r.finditer(b)]
        a = a.strip("()\n").split(",")
        b = b.strip("()\n").split(",")
        for ele, s in zip(a, a_keys):
            ind = bisect(b_keys, s, hi=len(b) - 1)
            print("{} -> {}".format(ele, b[ind]))

输出:

2- human rights -> 3- droits de l'homme
 10- workers rights ->  7- droit des travailleurs
2- human rights -> 5- droits de l'homme
 10- workers rights ->  15- les droits des femmes
 19- women rights ->  15- les droits des femmes

你需要修改格式并再做一次检查,根据ind和ind -1的ele的绝对差异找到min。

要捕捉前一个ind-1元素的绝对差异较小的位置:

from bisect import bisect
import re

with open("test.txt") as f:
    r = re.compile("(\d+)")
    for line in f:
        a, b = line.lstrip("0123456789. ").split(">> ")
        a_keys = [int(i.group()) for i in r.finditer(a)]
        b_keys = [int(i.group()) for i in r.finditer(b)]
        a = a.strip("()\n").split(",")
        b = b.strip("()\n").split(",")
        for ele, k in zip(a, a_keys):
            ind = bisect(b_keys, k, hi=len(b) - 1)
            ind -= k - b_keys[ind] < b_keys[ind-1] - k
            print("{} -> {}".format(ele, b[ind]))

所以:

1. (2- human rights, 10- workers rights)>> (3- droits de l'homme, 7- droit des travailleurs)
2. (2- human rights, 10- workers rights, 19- women rights)>> (1- droits de l'homme ,4- foobar, 15- les droits des femmes)

我们得到:

2- human rights -> 3- droits de l'homme
 10- workers rights ->  7- droit des travailleurs
2- human rights -> 1- droits de l'homme 
 10- workers rights ->  15- les droits des femmes
 19- women rights ->  15- les droits des femmes

原始代码会输出2- human rights -> 4- foobar,因为我们没有考虑前一个元素的绝对差异在哪里。

使用评论中的数据显示差异:

l1 = [10, 33, 50, 67]
l2 = [7, 16, 29, 55]

for s in l1:
    ind = bisect(l2, s, hi=len(l2) - 1)
    print("{} -> {}".format(s, l2[ind]))

输出:

10 -> 16
33 -> 55
50 -> 55
67 -> 55

现在检查前一个元素:

l1 = [10, 33, 50, 67]
l2 = [7, 16, 29, 55]

for s in l1:
    ind = bisect(l2, s, hi=len(l2) - 1)
    ind -= s - l2[ind-1] < l2[ind] - s
    print("{} -> {}".format(s, l2[ind]))

输出:

10 -> 7
33 -> 29
50 -> 55
67 -> 55

bisect.bisect

  

与bisect_left()类似,但返回插入点,该插入点位于a中x的任何现有条目之后(右侧)。   返回的插入点i将数组a分成两半,以便所有(对于[lo:i]中的val的val&lt; = x)用于左侧和all(val> x用于val中的[i:hi] ])对于右侧。

因此,二等分获取元素应该落在有序数字列表中的位置,所有元素都小于元素的左侧,这意味着元素大于之前的所有元素。为了根据差异找到最接近的值,我们需要检查前一个元素,因为abs差异可能更小。