如何组合包含间隔的两个列表

时间:2011-05-02 19:47:15

标签: python linux awk

我有列表1和2,我想得到列表3.如果有人可以建议python或awk脚本,那就太棒了。

List 1
A   100-160
B   200-500
C   800-1500
D   1600-2000
E   2500-3000

List 2
150
600
900
1700
2400


List 3
A   100-160        150
B   200-500 
C   800-1500    900
D   1600-2000   1700
E   2500-3000   

7 个答案:

答案 0 :(得分:2)

您可以从列表1中创建一个包含间隔的字典,然后遍历它以查看列表2中的任何值是否在范围内。例如,

list1 = {"A": [100, 160], "B": [200, 500], "C": [800, 1500],
         "D": [1600, 2000], "E": [2500,3000]}

list2 = [150, 600, 900, 1700, 2400]

for key, val in list1.iteritems():
    for num in list2:
        if num in range(val[0], val[1]):
            val.append(num)

for key, val in sorted(list1.iteritems()):
    print key, ":", val

答案 1 :(得分:2)

这是一个例子。期望在命令行上传递两个文件名。

import sys

if len(sys.argv) != 3:
    print 'parameters: list1 list2'
    sys.exit(1)

list1 = []
for line in file(sys.argv[1]):
    fields = line.split()
    f1 = fields[0]
    f2, f3 = fields[1].split('-')
    list1.append((f1, int(f2), int(f3), [], ))

for line in file(sys.argv[2]):
    value = int(line)
    for name, lb, ub, values in list1:
        if value >= lb and value <= ub:
            values.append(str(value))

for name, lb, ub, values in list1:
    if values: vals = ','.join(values)
    else: vals = ''
    print '%s %d-%d %s' % (name, lb, ub, vals, )

答案 2 :(得分:1)

你可以在Python中做这样的事情:

L1 = [(100, 160), (200, 500), (800, 1500), (1600, 2000), (2500, 3000)]
L2 = [150, 600, 900, 1700, 2400]
L3 = [((a, b), [i for i in L2 if a<=i<b]) for (a, b) in L1]

如果这是您想要的(并将其打印出来),很容易将数据解析到该结构中,但我会等到您解释数据的格式以及您需要的格式,因为我有一种感觉会有一个接受它。

答案 3 :(得分:1)

只需在命令行上执行即可。到目前为止,这是所有中唯一的awk解决方案:

 paste list1 list2|awk '{split($2,a,"-");
                           if($3>a[1] && $3<a[2])
                           {h=$3}
                           else
                           {h=""};
                           print $1,$2,h}'

A 100-160 150
B 200-500
C 800-1500 900
D 1600-2000 1700
E 2500-3000

答案 4 :(得分:0)

Dunno肯定是否需要Ruby,但这里有一个快速通过:

list1 = %w[ A 100-160 B 200-500 C 800-1500 D 1600-2000 E 2500-3000 ]
list2 = %w[ 150, 600, 900, 1700, 2400 ]

list3 = []

list1.each_slice(2) do |char, range|
  min_range, max_range = range.split('-').map{ |i| i.to_i }
  l2 = list2.shift
  case l2.to_i
  when min_range..max_range
    list3 << [ char, range, l2 ]
  else
    list3 << [ char, range ]
  end
end

require 'pp'
pp list3

>> [["A", "100-160", "150,"],
>>  ["B", "200-500"],
>>  ["C", "800-1500", "900,"],
>>  ["D", "1600-2000", "1700,"],
>>  ["E", "2500-3000"]]

答案 5 :(得分:0)

这是我的看法。我刚刚编写了解析和打印位,因为你没有指定。

list_1 = ['A\t100-160', 'B\t200-500', 'C\t800-1500', 'D\t1600-2000', 'E\t2500-3000']
list_2 = [150, 600, 900, 1700, 2400]

for range in list_1:
    # parse the input (this may be different, but you didn't specify)
    lower_bound, upper_bound = range.split('\t')[1].split('-')  # this is a bit fragile
    lower_bound = int(lower_bound)
    upper_bound = int(upper_bound)

    # make sure lower_bound is less than upper_bound
    if upper_bound < lower_bound:
        (lower_bound, upper_bound) = (upper_bound, lower_bound)

    # loop over list 2 and see if any fall into the current range
    items_in_range = [str(number) for number in list_2 if lower_bound <= number < upper_bound]

    # output List 3
    print range + '\t' + ','.join(items_in_range)

答案 6 :(得分:0)

您可以使用可迭代工具来编写此代码。不是太可读,但这有效。绝对有趣的写作!

from itertools import chain

nameranges = ['A', '100-160', 'B', '200-500', 'C', '800-1500', 'D', '1600-2000', 
              'E', '2500-3000']

values = [150, 600, 900, 1700, 2400]
z = zip(nameranges[0::2], ( map(int, x.split("-")) for x in nameranges[1::2]))
f = list(chain(* (map(lambda x, y: (x[0][0], x[1][0], x[1][1], y) 
               if x[1][0]<=y<=x[1][1] else (x[0], x[1][0], x[1][1]), 
               z, values))))
# print f
#['A', 100, 160, 150, 'B', 200, 500, 'C', 800, 1500, 900, 'D', 1600, 2000, 1700, 
# 'E', 2500, 3000]