2015-09-26 39 views
1

說我有一個任意名單:的Python:轉換任意結構嵌套列表的HTML

qw = ['a', [['tag', '1'], ['tag', '2']]] 

我需要建立HTML與<blockquote>(只是一個Python字符串,列表中的每個元素應相應地包裹在標籤到層次):

<blockquote> a 
    <blockquote> tag 
     <blockquote> 1 </blockquote> 
    </blockquote> 
    <blockquote> tag 
     <blockquote> 2 </blockquote> 
    </blockquote> 
</blockquote> 

結果:

render

比如我有一個字符串test='str1str2str34'和一些規則將其分割成列表:

['str1str2str34', [ 
    ['str1', ['str', '1']], 
    ['str2', ['str', '2']], 
    ['str34', ['str', '3', '4']] 
    ] 
] 

基於的渲染結果BLOCKQUOTE標籤:

render3

所以,我試圖改變遞歸發電機(用於展平列表):

def flatten(l): 
    for el in l: 
     if isinstance(el, collections.Iterable) and not isinstance(el, basestring): 
      for sub in flatten(el): 
       yield sub 
     else: 
      yield el 

但是真的沒有什麼c它的。

+0

'名單(壓扁(QW))'。 – ekhumoro

回答

0

隨着時間的推移,我已經找到了解決方案。

首先在我看來字典更適合這種情況。

爲了節省,我們可以使用OrderedDict順序:我們使用遞歸發電機

j = OrderedDict([ 
    ('str1str2str34', OrderedDict([ 
     ('str1', ['str', '1']), 
     ('str2', ['str', '2']), 
     ('str34', ['str', '3', '4']) 
    ])) 
]) 

解決這個任務:

tag = 'blockquote' 

def recurse(d, tag): 
    if isinstance(d, (dict, OrderedDict)): 
     for k in d: 
      yield '<' + tag + '>' + k 
      for sub in recurse(d[k], tag): 
       yield sub 
      yield '</' + tag + '>' 
    elif isinstance(d, (list, tuple)): 
     d = ['<{1}>{0}</{1}>'.format(el, tag) for el in d] 
     yield '<' + tag + '>' + ' '.join(d) + '</' + tag + '>' 

print '\n'.join(list(recurse(j, tag))) 

下面是美化HTML。

<blockquote>str1str2str34 
 
    <blockquote>str1 
 
     <blockquote> 
 
      <blockquote>str</blockquote> 
 
      <blockquote>1</blockquote> 
 
     </blockquote> 
 
    </blockquote> 
 
    <blockquote>str2 
 
     <blockquote> 
 
      <blockquote>str</blockquote> 
 
      <blockquote>2</blockquote> 
 
     </blockquote> 
 
    </blockquote> 
 
    <blockquote>str34 
 
     <blockquote> 
 
      <blockquote>str</blockquote> 
 
      <blockquote>3</blockquote> 
 
      <blockquote>4</blockquote> 
 
     </blockquote> 
 
    </blockquote> 
 
</blockquote>