0

I have a very specific problem. I have six lists that I need to combine into one big string. Every list will be enclosed inside a bracket () in final big string.

For example, I have declared six lists as below:

primaryP=['PSUP']
primaryG=['NSUP']
primaryAin=['IBIAS_200N','VREF']
primaryAout=['IOUTN','IOUTP','IBIAS_OUT<1:0>','ICAL<1:0>']
primaryDin=['DN', 'DNB', 'EN', 'FAST_START', 'RESET', 'UP', 'UPB', 'DEGEN_TRIM<2:0>']
primaryDout=[]

Now I want to combine all six lists into one big string as shown below:

CSRPGPrimary='//CSRPG PRIMARY ("PSUP") ("NSUP") ("IBIAS_200N" "VREF") ("IOUTN" "IOUTP" "IBIAS_OUT<1>" "IBIAS_OUT<0>" "ICAL<1>" "ICAL<0>") ("DN" "DNB" "EN" "FAST_START" "RESET" "UP" "UPB" "DEGEN_TRIM<2>" "DEGEN_TRIM<1>" "DEGEN_TRIM<0>") ()'

Notice how I want every list inside individual brackets () and each element in double quotes "". Also I want to split bus/vector bits individually in final string as shown above.

Here is what I tried so far:

primaryP=['PSUP']
primaryG=['NSUP']
primaryAin=['IBIAS_200N','VREF']
primaryAout=['IOUTN','IOUTP','IBIAS_OUT<1:0>','ICAL<1:0>']
primaryDin=['DN', 'DNB', 'EN', 'FAST_START', 'RESET', 'UP', 'UPB', 'DEGEN_TRIM<3:0>']
primaryDout=[]

primaryMaster=[primaryP, primaryG, primaryAin, primaryAout, primaryDin, primaryDout]
CSRPGPrimary=['("'+' '.join(item)+'")' if item else '()' for item in primaryMaster]
CSRPGPrimary="//CSRPG PRIMARY " + ' '.join(CSRPGPrimary)

print("CSRPGPrimary=", CSRPGPrimary)

But final output is not as I wanted:

Final output:
('CSRPGPrimary=', '//CSRPG PRIMARY ("PSUP") ("NSUP") ("IBIAS_200N VREF") ("IOUTN IOUTP IBIAS_OUT<1:0> ICAL<1:0>") ("DN DNB EN FAST_START RESET UP UPB DEGEN_TRIM<1:0> GAIN_SEL<1:0> GAIN_TRIM<3:0> OFFSET_MODE<1:0> OFFSET_TRIM<3:0> RES_TRIM<4:0> SEL_IRN<1:0> SEL_IRP<1:0>") ()')

Desired output:
('CSRPGPrimary=', '//CSRPG PRIMARY ("PSUP") ("NSUP") ("IBIAS_200N" "VREF") ("IOUTN" "IOUTP" "IBIAS_OUT<1>" "IBIAS_OUT<0>" "ICAL<1>" "ICAL<0>") ("DN" "DNB" "EN" "FAST_START" "RESET" "UP" "UPB" "DEGEN_TRIM<2>" "DEGEN_TRIM<1>" "DEGEN_TRIM<0>") ()')

any suggestions, especially what is best way to split vector/bus bits?

3
  • It looks like you want to do the "-wrapping to each of the elements you join, but your code is doing it to the result of the join. It's just a matter of swapping that order. Commented Mar 13, 2018 at 23:14
  • Wait, do you actually want "IBIAS"_"200N" instead of "IBIAS_200N"? If so, what's the rule for that? Split on non-alpha characters, quote the bits, and rejoin? Or…? Commented Mar 13, 2018 at 23:21
  • it was a typo, corrected now Commented Mar 13, 2018 at 23:25

1 Answer 1

1

It's probably simpler to do this in steps. If you really want to merge it all back into one monster listcomp that you can't debug, you can do that after you get it working.

The first thing we want to do is turn each bus-bits spec into separate elements. This is the trickiest bit. I'm not sure of the exact rule you're using, but it would go something like this:

def split_bus_bits(lst):
    for element in lst:
        if element.endswith('>'):
            base, _, bits = element[:-1].partition('<')
            hi, lo = bits.split(':')
            for i in range(int(lo), int(hi)+1):
                yield f'{base}<{i}>'
        else:
            yield element

Or, if you can understand regular expressions, this seems like a good job for one:

rbusbits = re.compile(r'(\w+)(?:<(\d+):(\d+)>)?')
def split_bus_bits(lst):
    for element in lst:
        base, hi, lo = rbusbits.match(element).groups()
        if hi:
            for i in range(int(lo), int(hi)+1):
                yield f'{base}<{i}>'
        else:
            yield base

And now, we can expand out each sublist:

busbitsified = (split_bus_bits(sublist) for sublist in primaryMaster)            

The remaining steps are all a lot simpler. For each list, we want to put each element in quotes:

quoted = ([f'"{element}"' for element in sublist] for sublist in busbitsified)

Next, join each sublist:

joined = (' '.join(sublist) for sublist in quoted)

Next, put parens around each string-that-was-a-joined-up-sublist:

parenthesized = (f'({sublist})' for sublist in joined)

And finally, join them into one big string:

CSRPGPrimary="//CSRPG PRIMARY " + ' '.join(parenthesized)

And the result seems to be your desired one:

'//CSRPG PRIMARY ("PSUP") ("NSUP") ("IBIAS_200N" "VREF") ("IOUTN" "IOUTP" "IBIAS_OUT<1:0>" "ICAL<1:0>") ("DN" "DNB" "EN" "FAST_START" "RESET" "UP" "UPB" "DEGEN_TRIM<3:0>") ()'

Notice that I didn't have to do anything special for (). An empty sublist will quote no elements, join those no elements into an empty string, and then parenthesize that empty string.


If you're not using Python 3.6+, or just don't understand f-strings, you can replace those with your favorite calls to str.format or % or just concatenation (e.g., '"' + element + '"').


From your output, it looks like you're using Python 2.7, but writing code as if you were using Python 3. In which case you should probably either from __future__ import print_function, or change your print statements to remove the extraneous parentheses. Unless you actually wanted to print a tuple of the reprs of two strings, instead of just printing two strings. In that case, carry on.

Sign up to request clarification or add additional context in comments.

22 Comments

any suggestions on splitting bus bits?
I tried with python 3.6 and it works great. regex function for bus bit expansion is working as expected however the first function outputs full bus width as well. I like the regex one though. CSRPGPrimary= //CSRPG PRIMARY ("PSUP") ("NSUP") ("IBIAS_200N" "VREF") ("IOUTN" "IOUTP" "IBIAS_OUT<1:0><0>" "IBIAS_OUT<1:0><1>" "ICAL<1:0><0>" "ICAL<1:0><1>") ("DN" "DNB" "EN" "FAST_START" "RESET" "UP" "UPB" "DEGEN_TRIM<3:0><0>" "DEGEN_TRIM<3:0><1>" "DEGEN_TRIM<3:0><2>" "DEGEN_TRIM<3:0><3>") ()
@sanforyou You probably want a step either right before or right after parenthesization. The first would be something like spaced = (sublist if sublist else ' ' for sublist in joined), the second something like spaced = ('( )' if substr == '()' else substr for substr in parenthesized). If you understand how either of those works, you can merge it into the previous or next step in the pipeline pretty easily.
@sanforyou Also, it's worth learning how to translate comprehensions into for statements and back. [f(x) for x in xs if p(x)] is the same as result=[] then for x in xs: then if p(x): then result.append(f(x)). The clauses of the comprehension just become nested statements, in order. The only difference with a generator expression (using parens instead of square brackets) is that it doesn't have to build a list in memory, it gives you the values lazily on demand.
@sanforyou There's a great presentation called Generator Tricks for Systems Programmers that explains more about this style of organizing your code into a sequence of generator expressions. I think David Beazley explains it better than I ever could, even if I weren't limited by the scope of a StackOverflow answer and comments, so you should check it out.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.