Python - expanding the range between dot dot (id1..id2)
<p>Suppose i have a list of ids like:  </p>

<pre><code>ids= 1/1/n1..1/1/n5 , 1/1/x1 , 1/1/g1
</code></pre>

<p>Expected output: </p>

<pre><code>1/1/n1 , 1/1/n2 , 1/1/n3 , 1/1/n4 , 1/1/n5 ,1/1/x1, 1/1/g1
</code></pre>

<p>Means wherever i finds 'ids..ids', i will fill the gap </p>

<p>I have written a very basic code, but i am looking for more pythonic solution</p>

<pre><code>import re
ports_list=['1/1/n1..1/1/n8']

n = 2
port_range=[]
for port in ports_list:
    if '..' in port:
        groups = port.split('..')     #gives  ['1/1/n1', '1/1/n8']
        for item in groups:
            port_split = item.split('/')
            port_join='/'.join(port_split[:n]), '/'.join(port_split[n:])
            port_join=port_join[0]+"/"
            port_split=port_split[2]    # n1     n8
            get_str=port_split[0][0]
            num=re.findall(r'\d+', port_split) # 1 8
            port_range.append(num[0])
        #remove port with '..
        ports_list.remove(port)

n1=port_range[0]
n2=port_range[1]
final_number_list=list(range(int(n1),int(n2)+1))
my_new_list = [ get_str + str(n) for n in final_number_list]
final_list=[ port_join + str(n) for n in my_new_list]
ports_list=ports_list+final_list
print ports_list
</code></pre>

<p>Gives Expected Output:  </p>

<pre><code>['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/n6', '1/1/n7', '1/1/n8']
</code></pre>

<p>But how it can be solved easily , without complex logic ? </p>

<p>Not sure it is more readable or better than your current approach, but we can use regular expressions to extract the common part and the range borders from a string:</p>

<pre><code>import re


def expand(l):
    result = []
    pattern = re.compile(r"^(.*?)(\d+)$")
    for item in l:
        # determine if it is a "range" item or not
        is_range = '..' in item
        if not is_range:
            result.append(item)
            continue

        # get the borders and the common reusable part
        borders = [pattern.match(border).groups() for border in item.split('..')]
        (common_part, start), (_, end) = borders

        for x in range(int(start), int(end) + 1):
            result.append("%s%d" % (common_part, x))

    return result

print(expand(['1/1/n1..1/1/n8']))
print(expand(['1/1/n1..1/1/n5', '1/1/x1', '1/1/g1']))
</code></pre>

<p>Prints:</p>

<pre><code>['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/n6', '1/1/n7', '1/1/n8']
['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/x1', '1/1/g1']
</code></pre>

<p>where in <code>^(.*?)(\d+)$</code>:</p>

<ul>
<li><code>^</code> matches the beginning of a string (not actually needed in our case since we use <code>.match()</code> - it will start searching from the beginning of a string anyway - leaving it there just because "Explicit is better than implicit")</li>
<li><code>(.*?)</code> is a capturing group that saves any characters any number of times in a <a href="http://stackoverflow.com/questions/2301285/what-do-lazy-and-greedy-mean-in-the-context-of-regular-expressions">non-greedy fashion</a></li>
<li><code>(\d+)</code> is a capturing group that would save one or more consecutive digits</li>
<li><code>$</code> matches the end of a string</li>
</ul>

python list python-2.7