2011-05-02 46 views
2

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

+1

它與清單2增加了只有在列表2的值是列表1的值之間? – utdemir 2011-05-02 19:50:51

+0

請明確您的邏輯是合併和排序結果。我已經從這個問題中刪除了'ruby'標籤,因爲您沒有使用Ruby要求解決方案。如果你願意這樣做,請編輯你的問題說出來。 – Phrogz 2011-05-02 19:53:05

+0

您是否需要一個Ruby腳本,忘記將其添加到問題中,或者您是否意外添加了Ruby標記? – 2011-05-02 19:57:36

回答

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

感謝FuzzyWuzzy。這很好,除了我不得不將原來的名字Solyc08g007690.1.1改爲1,2,3 .. – user690462 2011-05-02 21:18:04

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 
+0

與此相關的一個問題是,他將失去列表1的排序(python會隨機化鍵的順序)。當我運行它時,會出現「A,C,B,E,D」。 – 2011-05-02 20:06:07

+0

如果range很大,最好在'range()'上使用'xrange()'。 – jathanism 2011-05-02 20:10:22

+0

那麼,xrange的事情真的只是真正的大數字,其中內存是一個問題。就像試圖計算所有不到10億的素數一樣。 Xrange對此會有好處。對於這樣的事情,範圍真的很好。要解決非排序問題,我只需要在字典循環打印時快速更改某些鍵的排序方式。 – 2011-05-02 20:16:49

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] 

可以很容易地將數據解析成結構如果這就是你想要的(和打印退了出來),但我等到你解釋數據的格式和你需要什麼格式時,因爲我有一種感覺,它會有一個問題。

+0

列表1和2分別位於兩個不同的文件中,我想創建列表3中的第三個文件。 – user690462 2011-05-02 20:08:29

+0

嗯,@FuzzyWuzzy做了很多我在此期間要做的事情,所以我想改變我的答案。 – 2011-05-02 20:22:48

0

說不上肯定,如果紅寶石是必要的,但這裏有一個快速的傳球吧:

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"]] 
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) 
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] 
1

這樣做只是在命令line.So到目前爲止,這是在所有的唯一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