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

发布于 2024-11-04 23:24:28 字数 277 浏览 0 评论 0原文

我有列表 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   

I have list 1 and 2 and I would like to get list 3. If anyone can suggest python or awk script, that would be great.

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   

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

苦笑流年记忆 2024-11-11 23:24:28

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

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

Here is an example. It is expecting two filenames to be passed on the command line.

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, )
泪眸﹌ 2024-11-11 23:24:28

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

You could make a dictionary from list 1 that contains the intervals then loops through it to see if any value in list 2 is inside the range. For example,

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
幸福不弃 2024-11-11 23:24:28

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

如果你想要的话,很容易将数据解析成该结构(并将其打印回来),但我会等到你解释数据的格式以及你需要的格式把它放进去,因为我有预感,会有一个陷阱。

You could do something like this in 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]

It's easy to parse the data into that structure if that's what you want (and print it back out), but I'll wait until you explain what format the data comes in and what format you need it in, because I have a feeling there will be a catch to it.

四叶草在未来唯美盛开 2024-11-11 23:24:28

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

Do it simply on the command line.So far this is the only awk solution among all:

 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
抱猫软卧 2024-11-11 23:24:28

不确定是否需要 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"]]

Dunno for sure if Ruby is needed, but here's a quick pass at it:

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"]]
夕嗳→ 2024-11-11 23:24:28

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

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]

You can use iterable tools to write this. Not all too readable but this works. Definitely was fun to write!

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]
ˇ宁静的妩媚 2024-11-11 23:24:28

这是我的看法。由于您没有指定,我只是弥补了解析和打印位。

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)

Here's my take. I just made up the parsing and printing bit since you didn't specify.

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文