2012-05-10 75 views
1

我有一个排序列表,我想插入一个字符串,如果它匹配列表中的模式。匹配并插入python排序列表

Example : 

Sorted List 
['Amy Dave', 'Dee Waugh', 'Eva A', 'Gin', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 

以上列表按排序顺序排列。我需要按排序顺序插入名称,并且如果名称已经存在,则应该在现有名称之前插入名称。

Example 
Name 'Eva Henry' 

由于Eva已经在列表中,因此匹配模式后应该在Eva A之前插入模式。如果名称不匹配,则应按排序顺序将其插入列表中。输出应该是这样的:

Sorted List 
    ['Amy Dave', 'Dee Waugh', 'Eva Henry', 'Eva A', 'Gin', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 

任何帮助将不胜感激。

谢谢

+0

*“如果该名称已存在,那么它应该在现有名称之前插入“*我可以问为什么这个请求? –

+0

听起来像一个家庭作业问题。如果是,请将其标记为功课。 –

+0

我们对特权客户有这样的要求。是的它真的很奇怪,但它需要做:( – PratapSingh

回答

0

下面是一个完整的答案,你想要做什么,但可笑的。我没有测试任何边缘情况。

sorta_sorted_list = ['Amy Dave', 'Dee Waugh', 'Eva A', 'Gin', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 

print sorta_sorted_list 

def insert_kinda_sorted(name, sorta_sorted_list): 
    new_list = [] 
    fname = name.split()[0] 
    inserted = False 
    for index in range(len(sorta_sorted_list)): 
     if not inserted: 
      if sorta_sorted_list[index].split()[0] == fname: 
       new_list.append(name) 
       inserted = True 
      if sorta_sorted_list[index] > name: 
       new_list.append(name) 
       inserted = True 
     new_list.append(sorta_sorted_list[index]) 

    return new_list 

sorta_sorted_list = insert_kinda_sorted('Eva Henry', sorta_sorted_list) 
print sorta_sorted_list 

sorta_sorted_list = insert_kinda_sorted('Joe Blow', sorta_sorted_list) 
print sorta_sorted_list 

输出为:

['Amy Dave', 'Dee Waugh', 'Eva A', 'Gin', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 
['Amy Dave', 'Dee Waugh', 'Eva Henry', 'Eva A', 'Gin', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 
['Amy Dave', 'Dee Waugh', 'Eva Henry', 'Eva A', 'Gin', 'Joe Blow', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 
+1

您为什么帮助他们编写自杀程序并传播错误代码? :-)对不起,你的代码很好,我的意思是算法。 – gecko

+0

是的......在我重读那个之后,我意识到这个insort方法是行不通的。如果我们对这些名称进行标记,我们也可以创建一个字典,其中第一个标记是键,值是一个列表,我们将名字像堆栈一样推入,然后使用一个展开函数返回一个列表(或生成器)需要的时候。 – parselmouth

+0

优秀点[gecko](http://stackoverflow.com/users/774340/gecko)。如果要求如所描述(并且希望不是),则列表甚至不再是正确的数据结构。 – jgritty

0

OK,我会踏踏实实,投票支持这一点,但我不能让这种立场。这是一个糟糕的设计模式,如果这是家庭作业,你应该强烈抱怨。

我会将该名称作为一个带有频率的元组存储('Fred Bloggs',2),或者使用一个dict()或其他东西:只是任何东西,但请不要这样。 Google'python dict()'。

编辑:其实一个字典()是不是有序的吗?哦,我的生活失败了。耸肩。

编辑:我也是指元组列表。

+0

不知道一个元组是正确的数据结构,只有第一个名字似乎需要匹配。 – jgritty

+1

[heapq](http://docs.python.org/release/3.0.1/library/heapq.html)是一个不错的选择。 –

+0

@Jgritty:第二个元素是它出现的次数。第一个元素是全名。 – gecko

3

在我看来,没有愚蠢的问题。如果名称是全名,只有名字是排序的关键,那么总会有一些有趣的想法和需要解决的问题。您可以使用对开这样:

>>> fullnames = ['Amy Dave', 'Dee Waugh', 'Eva A', 'Gin', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 
>>> names = [full.split()[0] for full in fullnames] 
>>> names 
['Amy', 'Dee', 'Eva', 'Gin', 'Joy', 'Kay', 'Mae', 'Pam'] 

因此,我们必须将被用来寻找相同的方式,在前面的另一全名xx的位置(解压缩到x第一的名头名的平行名单情况下):

>>> xx = 'Eva Henry' 
>>> x = xx.split()[0] 
>>> x 
'Eva' 

现在,使用对开找到第一个名称列表所需位置:

>>> import bisect 
>>> pos = bisect.bisect_left(names, x) 

然后同时更新升派:

>>> fullnames.insert(pos, xx) 
>>> names.insert(pos, x) 

下面是结果:

>>> fullnames 
['Amy Dave', 'Dee Waugh', 'Eva Henry', 'Eva A', 'Gin', 'Joy Kola', 'Kay Min', 'Mae', 'Pam Deing'] 
>>> names 
['Amy', 'Dee', 'Eva', 'Eva', 'Gin', 'Joy', 'Kay', 'Mae', 'Pam'] 
0

这里是我的解决方案,我觉得它很容易

#spliting against whitespace 
first_name = name.split() 

#Stroting the first name of the user 
first_name = first_name[0] 

#Matching the pattern 
match = re.compile(first_name,re.IGNORECASE) 
ind = '' 

for i in sort_names: 
     if re.match(match, i): 
       ind = sort_names.index(i) 
       break 
       #If name matches for the first time end the loop and do insert name in the sorted list 

if ind != '': 
     sort_names.insert(ind, val) 
     print "" 
     print sort_names 
else: 
     bisect.insort(sort_names, val) 
     print sort_names