如何结合两个包含区间的列表

我有名单1和2,我想获得名单3.如果任何人可以build议pythonawk脚本,这将是伟大的。

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

清单2
 150
 600
 900
 1700
 2400


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

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

 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, ) 

您可以从列表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 

你可以在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] 

如果这是你想要的(把它打印出来),那么把数据解析成这个结构很容易,但是我会等到你解释数据格式和你需要什么样的格式,因为我有一种感觉将是一个抓住它。

只需在命令行上执行即可。到目前为止,这是唯一的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 

不知道是否需要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"]] 

你可以使用迭代工具来写这个。 不是所有的太可读,但这个工程。 绝对是有趣的写!

 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] 

这是我的要求 因为你没有指定,所以我只做了解析和打印。

 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)