Remove brackets from argv string - python

I am new to Python. I'm running Raspbian and calling a Python script this way:
python testarguments.py "Here is a test parameter"
My script:
import sys
print sys.argv[1:]
Output:
['Here is a test parameter']
Question:
What is the most efficient way to remove beginning and ending brackets and single quotes from sys.argv output?

You are slicing with
sys.argv[1:]
It means that get all the elements from 1 till the end of the sequence. That is why it creates a new list.
To get only the first item, simply do
sys.argv[1]
This will get the element at index 1.

The : sort of means 'and onwards' so it of course will return a list. Just do:
>>> sys.argv[1]
'Here is a test parameter'
Thus returning your first argument to executing the program, not a part of the list.

The other answers have addressed the actual issue for you, but in case you ever do encounter a string that contains characters you want to remove (like square brackets, for example), you could do the following:
my_str = "['Here is a test parameter']"
my_str.translate(None, "[]")
In other words, if the output you saw were actually a string, you could use the translate method to get what you wanted.

Related

unable to convert python type str into a list array

i'm new to python, and i am developing a tool/script for ssh and sftp. i noticed some of the code i'm using creates what i thought was a string array
channel_data = str()
to hold the console output from an ssh session. if i check "type" on channel_data it comes back as class 'str' ,
but yet if i perform for loop to read each item in channel_data , and channel_data contains what appears to be 30 lines from an ssh console
for line in channel_data:
if "my text" in line:
found = True
each iteration of "line" shows a single character, as if the whole ssh console output of 30 lines of text is broken down into single character array. i do have \n within all the text.
for example channel_data would contain "Cisco Nexus Operation System (NX-OS) Software\r\nCopyright (c) 2002-2016\r\n ..... etc. etc.. ", but again would read in my for loop and print out "C" then "i" then "s" etc..
i'm trying to understand do i have a char array here or a string array here that is made up of single string characters and how to convert it into a string list based on \n within Python?
You can iterate a string just like a list in Python. So, yes, as expected, your string type channel_data will in fact give you every character.
Python does not have a char array. You will have a list of strings, even as a single character as each item in the list:
>>> type(['a', 'b'])
<type 'list'>
Also, just for the sake of adding some extra information for your own knowledge when it comes to usage of terminology, there is a difference between array and list in Python: Python List vs. Array - when to use?
So, what you are actually looking to do here is take the channel_data string and make it a list by calling the split method on it.
The split method will, by default, split on white space characters only. Check the documentation. So, you will want to make sure what you want to actually split on and provide that detail to the method.
You can take a look at splitlines to see if that works for you.
As specified in the documentation for splitlines:
Line breaks are not included in the resulting list unless keepends is
given and true.
Your result will then be a list of strings as you expect. So, as an example you can do:
your_new_list_of_str = channel_data.split('\n')
or
your_new_list_of_str = channel_data.splitlines()
string_list = channel_data.splitlines()
See docs at https://docs.python.org/3.6/library/stdtypes.html#str.splitlines

joining a list with newline characters to pass as CL argument

I'm trying to join a list in python that contains several strings, some of which have \t and \n characters in them to create a string.
Say my list looks like this:
ll = ['list', 'of', '\tstrings', '\n\twith', 'newline', '\tcharacters']
ss = ':::'.join(ll)
print ss
prints ss with their \n and \t characters formatted:
list:::of::: strings:::
with:::newline::: characters\
While what I want it to print is:
'list:::of:::\tstrings:::\n\twith:::newline:::\tcharacters'
I've tried:
ss =[]
for l in ll:
ss.append(repr(l))
ss = ':::'.join(ll)
which does the same thing as above
and:
ss = ''
for l in ll:
ss += (repr(l)) + ':::'
print ss.strip(':::')
which is close but prints:
'list':::'of':::'\tstrings':::'\n\twith':::'newline':::'\tcharacters'
Tried a few more hacks but none seem to get me what I need.
The reason I need it like above is because I am writing CL arguments to a script that I call later on another machine. Passing a list as a CL argument doesn't work, so I was going to pass the list as a string (joined by ':::') and then on the other slide, split back into a list using ':::'. This works when just using join and split on the original list, however throws an error when I call the python script using the hardcoded CL arguments, because there's are newlines in list turned string argument. The last example works when passed through to the second machine, however gives me this list when I split it back:
["'list'", "'of'", "'\\tstrings'", "'\\n\\twith'", "'newline'", "'\\tcharacters'"]
when instead I need:
['list', 'of', '\tstrings', '\n\twith', 'newline', '\tcharacters']
UPDATE: I tried all of the suggestions below and more and still couldn't figure it out, so for now I'm just dumping the list into a text file on the first server, passing the file name instead of the list, then reading the text file to a list on the second server. Hopefully this workaround will work but i'm still looking for suggestions for a better way.
The joined string is already as you want it. You can confirm this by printing its representation:
ll = ['list', 'of', '\tstrings', '\n\twith', 'newline', '\tcharacters']
ss = ':::'.join(ll)
print repr(ss)
# 'list:::of:::\tstrings:::\n\twith:::newline:::\tcharacters'
Given the ss in your first code:
print ss.encode("string_escape")
(or possibly "unicode_escape" if there's any possibly of non-ASCII characters)
If you don't actually want the tabs and newlines for anything other than passing as arguments to some other system, you should probably use raw strings (r"\n\twith") to keep all the codes from ever being interpreted as escape codes.
No need to do data conversions that serve no purpose that you're just going to undo.

Iterating through python string array gives unexpected output

I was debugging some python code and as any begginer, I'm using print statements. I narrowed down the problem to:
paths = ("../somepath") #is this not how you declare an array/list?
for path in paths:
print path
I was expecting the whole string to be printed out, but only . is. Since I planned on expanding it anyway to cover more paths, it appears that
paths = ("../somepath", "../someotherpath")
fixes the problem and correctly prints out both strings.
I'm assuming the initial version treats the string as an array of characters (or maybe that's just the C++ in me talking) and just prints out characters.?...??
I'd still like to know why this happens.
("../somepath")
is nothing but a string covered in parenthesis. So, it is the same as "../somepath". Since Python's for loop can iterate through any iterable and a string happens to be an iterable, it prints one character at a time.
To create a tuple with one element, use comma at the end
("../somepath",)
If you want to create a list, you need to use square brackets, like this
["../somepath"]
paths = ["../somepath","abc"]
This way you can create list.Now your code will work .
paths = ("../somepath", "../someotherpath") this worked as it formed a tuple.Which again is a type of non mutable list.
Tested it and the output is one character per line
So all is printed one character per character
To get what you want you need
# your code goes here
paths = ['../somepath'] #is this not how you declare an array/list?
for path in paths:
print path

striplines() not working when using finditer python

I am trying to convert a multiline string to a single list which should be possible using splitlines() but for some reason it continues to convert each line into a list instead of processing all the lines at once. I tried to do it out of the for loop but doesnt seem to have any effect. I need the lines as a single list to use it another function. Below is how I get the multiline into a single variable. What am I missing???
multiline_string_final = []
for match_multiline in re.finditer(r'(^(\w+):\sThis particular string\s*|This particular string\s*)\{\s(\w+)\s\{(.*?)\}', string, re.DOTALL):
multi_line_string = match_multiline.group(4)
print multiline_string
This last print statement prints out the strings like this:
blah=0; blah_blah=1; Foo=3;
blah=4; blah_blah=5; Foo=0;
However I need:
['blah=0; blah_blah=1; Foo=3;''blah=4; blah_blah=5; Foo=0;']
I understand it has to be something with the finditer but cant seem to rectify.
Your new problem also has nothing to do with finditer. (Also, your code is still not an MCVE, you still haven't shown us the sample input data, etc., making it harder to help you.)
From this desired output:
['blah=0; blah_blah=1; Foo=3;''blah=4; blah_blah=5; Foo=0;']
I'm pretty sure what you're looking for is to get a list of the matches, instead of printing out each match on its own. That isn't a valid list, because it's missing the comma between the elements,* but I'll assume that's a typo from you making up data instead of building an MCVE and copying and pasting the real output.
Anyway, to get a list, you have to build a list. Printing things to the screen doesn't build anything. So, try this:
multiline_string_final.append(multiline_string)
Then, at the end—not inside the loop, only after the loop has finished—you can print that out:
print multiline_string_final
And it'll look like this:
['blah=0; blah_blah=1; Foo=3;',
'blah=4; blah_blah=5; Foo=0;']
* Actually, it is a valid list, because adjacent strings get concatenated… but it's not the string you wanted, and not a format Python would ever print out for you.
The problem has nothing to do with the finditer, it's that you're doing the wrong thing:
for line in multiline_string:
print multiline_string.splitlines()
If multiline_string really is a multiline string, then for line in multiline_string will iterate over the characters of that string.
Then, within the loop, you completely ignore line anyway, and instead print multiline_string.splitlines()).
So, if multiline_string is this:
abc
def
Then you'll print ['abc\n', 'def\n'] 8 times in a row. That's not what you want (or what you described).
What you want to do is:
split the string into lines
loop over those lines, not over the original un-split string
print each line, not the whole thing
So:
for line in multiline_string.splitlines():
print line

Compare & manipulate strings with python

I've written an XML parser in Python and have just added functionality to read a further script from a different directory.
I've got two args, first is the path where I'm parsing XML. Second is a string in another XML file which I want to match with the first path;
arg1 = \work\parser\main\tools\app\shared\xml\calculators\2012\example\calculator
path = calculators/2012/example/calculator
How can I compare the two strings to match identify that they're both referencing the same thing and also, how can I strip calculator from either string so I can store that & use it?
edit
Just had a thought. I have used a Regex to get the year out of the path already with year = re.findall(r"\.(\d{4})\.", path) following a problem Python has with numbers when converting the path to an import statement.
I could obviously split the strings and use a regex to match the path as a pattern in arg1 but this seems a long way round. Surely there's a better method?
Here I am assuming you are actually talking about strings, and not file paths - for which #mgilson's suggestion is better
How can I compare the two strings to match identify that they're both
referencing the same thing
Well first you need to identify what you mean by "the same thing"
At first glance it seems that if the the second string ends with the first string with the reversed slash, you have a match.
arg1 = r'\work\parser\main\tools\app\shared\xml\calculators\2012\example\calculator'
arg2 = r'calculators/2012/example/calculator'
>>> arg1.endswith(arg2.replace('/','\\'))
True
and also, how can I strip calculator from
either string so I can store that & use it?
You also need to decide if you want to strip the first calculator, the last calculator or any occurance of calculator in the string.
If you just want to remove the last string after the separator, then its simply:
>>> arg2.split('/')[-1]
'calculator'
Now to get the orignal string back, without the last bit:
>>> '/'.join(arg2.split('/')[:-1])
'calculators/2012/example'
check out os.path.samefile:
http://docs.python.org/library/os.path.html#os.path.samefile
and os.path.dirname:
http://docs.python.org/library/os.path.html#os.path.dirname
or maybe os.path.basename (I'm not sure what part of the string you want to keep).
Here, try this:
arg1 = "\work\parser\main\tools\app\shared\xml\calculators\2012\example\calculator"
path = "calculators/2012/example/calculator"
arg1=arg1.replace("/","\\")
path=path.replace("/","\\")
if str(arg1).endswith(str(path)) or str(path).endswith(str(arg1)):
print "Match"
That should work for your needs. Cheers :)

Categories