Split List based on range into multiple list :PYTHON - python

I have a small doubt , and i was not able to solve it , consider i have a list seperated with comma , and the data is dynamic may be 2 data or more than that
example : listVaue = ['Server1,Stop,Server2,START,.....,ServerN,StartN/StopN']
where N is a number
so if i have to split this into something like [[Server1,Stop],[Server2,Start2],....[ServerN,StartN/StopN]]
Is this possible . I wrote a code , but it is not working properly
listVaue = ['Server1,Stop,Server2,START']
c_index = listVaue.index("Stop")
l2 = listVaue[:c_index]
print(l2)
Can anyone help me solve this problem

This should work:
listValue = ["server1, stop, server2, start"]
listValue = listValue[0].split(",")
l2 = [[first_item, second_item] for first_item, second_item in zip(listValue[0::2], listValue[1::2])]

If you have a list defined as:
listVaue = ['Server1,Stop,Server2,START']
it actually only has one value, which is a string of value 'Server1,Stop,Server2,START'. If you can define a different list, I would suggest trying to do:
listVaue = ['Server1', 'Stop', 'Server2', 'START']
or even a list of tuples, if you would like values to be correspondent:
listVaue = [('Server1', 'Stop'), ('Server2', 'START')]
Now, if you don't have control over the input data (and therefore cannot change the original list), what you can do is to first split all values by comma and then aggregate them 2 by 2.
# Original list
listVaue = ['Server1,Stop,Server2,START']
# Split string into separate values
# Take the first element - from your code it looks
# like you only have a continuous string
new_list = listVaue[0].split(',')
# If you know that the list length will always be even, you can
# aggregate them 2 by 2 using the following code:
l2 = [(new_list[i], new_list.pop(i + 1)) for i in range(len(new_list) // 2)]
l2
>>> [('Server1', 'Stop'), ('Server2', 'START')]
What the code does is basically to get elements in position i and the next one as well (i + 1), removing the latter, whilst iterating through half the length of the list. Because you change its size as you iterate, always removing the second item, you'll end up only iterating through the original indexes 0, 2, 4, 6, 8..., whilst also retrieving their counterpart (1, 3, 5, 7, 9...).
Please note that changing the size of a list whilst you iterate is not generally a good practice, but because we are copying the original list, it shouldn't be a big problem for your case.
You can also change my code to whatever suits you, and you're probably better off with a normal for loop instead of a list comprehension:
listVaue = ['Server1,Stop,Server2,START']
new_list = listVaue[0].split(',')
l2 = []
for i in range(len(my_list) // 2):
# Change square brackets to round ones if you want a tuple (immutable) instead
l2.append([new_list[i], new_list.pop(i + 1)]
print(l2)

Try this:
listVaue = ['Server1,Command1,9182,Running,START,Server2,Command2,8888,Running,RESTART,ServerN,CommandN,N,Running,restart']
listVaue = listVaue[0].split(',')
a = ['START', 'RESTART', 'STOP', 'BOUNCE']
s = []
l2 = []
for i in listVaue:
s.append(i)
if i.upper() in a:
l2.append(s)
s = []

Related

How Do I create a new list from distinct elements of existing list?

I have a list
current_list = [#,'1','2','3','4','5','6','7','8','9']
I want to create a new list by indexing current_list such that
new_list = ['1','5','9']
I have tried
new_list = current_list[1] + current_list[5] + current_list[9]
but I get
>>> 159
and not
>>> ['1','5','9']
How do I create new_list from current_list such that
new_list = ['1','5','9'] ?
New to programming and appreciate your patience.
you are adding list items by using + sign . Try:
new_list = [current_list[1] , current_list[5] , current_list[9]]
your list must contain at least 10 item otherwise you will get index out of bound error
You can do this if you want your result. For the new list the elements needs to be arranged as list.'+' sign is used esp. in strings (concationation) or simple addition process. So,
current_list = ['#','1','2','3','4','5','6','7','8','9']
new_list=[current_list[1],current_list[5],current_list[9]]
Instead of hard-coding the indexes (e.g. [current_list[1],current_list[5],current_list[9]]), I would recommend programatically inserting the indexes so that it is easy to modify in the future, or you can easily generate the indexes you want from a function
indexes = [1, 5, 9]
current_list = ['#','1','2','3','4','5','6','7','8','9']
new_list = [current_list[i] for i in indexes]
## gives ['1','5','9']
Now, if you need to change the indexes, you can just modify the indexes line.
Or, if down the road a user needs to specify the indexes from a file, you can read those numbers from a file. Either way, the way you generate new_list from current_list stays the same. (As a new programmer, it is important that you learn early the importance of writing code so that it is easy to modify in the future.)
from operator import itemgetter
def make_list_from(*indices, lst):
# Create a function that will get values from given indices
values = itemgetter(*indices)
# Get those values as a tuple and convert them into a list
return list(values(lst))
current_list = ['0', '1','2','3','4','5','6','7','8','9']
print(make_list_from(1, 5, 9, lst=current_list))
# ['1', '5', '9']
you can use itemgetter:
from operator import itemgetter
my_indices = [1, 5, 9]
new_list = list(itemgetter(*my_indices)(current_list))
or you can pick the elements by your indeces using list comprehension:
new_list = [current_list[i] for i in my_indices]
similar with:
new_list = []
for index in my_indices:
new_list.append(current_list[index])
print(new_list)
output:
['1', '5', '9']

Find the missing strings containing int value from a given list

Given a list of string, say mystr= ["State0", "State1", "State2", "State5", "State8"].
I need to find the missing States (here "State3", "State4", "State6", "State7"). Is there a possibility to find it?
Desired output: mylist = ["State3", "State4", "State6", "State7"]
Assuming the highest number in the list might not be known, one way is to extract the numerical part in each string, take the set.difference with a range up to the highest value and create a new list using a list comprehension:
import re
ints = [int(re.search(r'\d+', i).group(0)) for i in mystr]
# [0, 1, 2, 5, 8]
missing = set(range(max(ints))) - set(ints)
# {3, 4, 6, 7}
[f'State{i}' for i in missing]
# ['State3', 'State4', 'State6', 'State7']
Simple enough with list comprehensions and f-strings:
mystr = ["State0", "State1", "State2", "State5", "State8"]
highest = max(int(state.split('State')[-1]) for state in mystr)
mylist = [f"State{i}" for i in range(highest) if f"State{i}" not in mystr]
print(mylist)
Output:
['State3', 'State4', 'State6', 'State7']
Note that this solution is nice and general and will work even if the last element in the original list if for example "State1024", and even if the original list is not sorted.
I am not sure what you are asking. I think this is what you expect.
mystr= ["State0", "State1", "State2", "State5", "State8"]
print(['State'+str(p) for p in range(8) if 'State'+str(p) not in mystr ])
You can use the following solution:
lst = ["State0", "State1", "State2", "State5", "State8"]
states = set(lst)
len_states = len(states)
missing = []
num = 0
while len_states:
state = f'State{num}'
if state in states:
len_states -= 1
else:
missing.append(state)
num += 1
print(missing)
Output:
['State3', 'State4', 'State6', 'State7']

Appending / concatenating one string to elements of a list of strings (Python 3.5)

Perhaps this has been answered, but I sincerely could not find it.
I wish to have a specific output in the form of:
("A_1", "A_2", ..., "A_100")
I tried:
a = "A_"
nums_1_100 = str(list(range(1,101)))
for i in range (1,101):
x = a
x += nums_1_100
And this returns:
'A_[1, 2, 3, 4, 5, ..., 100]'
Your code makes no sense as you overwrite x each iteration, which in result kills what your code produced in previous one. You want rather to use simple list comprehension instead:
result = [ 'A_%d' % i for i in range(1,101)]
which would then produce list with elements like A_1, A_2 ...
Try a list comprehension to make that list of strings like:
x = ['A_{}'.format(i) for i in range(1, 101)]
Here is the functional approach. This will work with a list of any type, so if you decided to switch from ints at the end to strings/characters, all that would need to change would be the contents of listToAppend.
listToAppend = list(range(1, 101))
output = list(map(lambda x: "A_" + str(x), listToAppend))

Reverse characters of string in subset of 3

Let say my string is as:
x = 'abcdefghi'
I want to reverse it in subsets of 3, so that my output is:
x = 'cbafedihg'
i.e. 0th index is swapped with 2nd index, 3rd index swapped with 5th, and so on.
Below is my code based on converting the string to list and swap the elements within the list:
string_list = list(x)
for i in range(len(string_list)/3):
string_list[i*3], string_list[i*3+2] = string_list[i*3+2], string_list[i*3]
''.join(string_list)
# Output: 'cbafedihg'
I want to know what will be the most efficient and most pythonic way to achieve it.
Note: len(x)%3 will always be 0.
The above code can be written using string slicing and list comprehension as:
# Here x[i*3:i*3+3][::-1] will reverse the substring of 3 chars
>>> ''.join([x[i*3:i*3+3][::-1] for i in range(len(x)/3)])
'cbafedihg'
Based on the comment by Delgan, it could be further simplified using step as 3 with range itself as:
>>> ''.join(x[i:i+3][::-1] for i in range(0, len(x), 3))
'cbafedihg'
Writing a function that is more readable and flexible?
def get_string(input_str, step=3):
output = ""
i = 0
for _ in list(input_str):
if i == len(input_str):
return output
elif i+step-1 >= len(input_str):
output += input[len(input_str)-1:i-1:-1]
return output
else:
output += input_str[i+step-1:i:-1] + input_str[i]
i += step
return output
And here comes the flexible part:
get_string("abcdefghi")
# Ouputs 'cbafedihg'
get_string("abcdefghi", 2)
# Outputs 'badcfehgi'
get_string("abcdefghi", 5)
# Outputs 'edcbaihgf'
Not to mention, if you want to add some more logic or change the logic, it is easier to change here.
Another alternative to achieve this is to type-cast your string to list, then simply swap the elements of list using list slicing with step as 3, and join back the list of strings as:
>>> string_list = list(x)
>>> string_list[::3], string_list[2::3] = string_list[2::3], string_list[::3]
>>> ''.join(string_list)
'cbafedihg'

Python List Comprehension Setting Local Variable

I am having trouble with list comprehension in Python
Basically I have code that looks like this
output = []
for i, num in enumerate(test):
loss_ = do something
test_ = do something else
output.append(sum(loss_*test_)/float(sum(loss_)))
How can I write this using list comprehension such as:
[sum(loss_*test_)/float(sum(loss_))) for i, num in enumerate(test)]
however I don't know how to assign the values of loss_ and test_
You can use a nested list comprehension to define those values:
output = [sum(loss_*test_)/float(sum(loss_))
for loss_, test_ in ((do something, do something else)
for i, num in enumerate(test))]
Of course, whether that's any more readable is another question.
As Yaroslav mentioned in the comments, list comprehensions don't allow you to save a value into a variable directly.
However it allows you to use functions.
I've made a very basic example (because the sample you provided is incomplete to test), but it should show how you can still execute code in a list comprehension.
def loss():
print "loss"
return 1
def test():
print "test"
return 5
output = [loss()*test() for i in range(10) ]
print output
which is this case will result in a list [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
I hope this somehow shows how you could end up with the behaviour that you were looking for.
ip_list = string.split(" ") # split the string to a list using space seperator
for i in range(len(ip_list)): # len(ip_list) returns the number of items in the list - 4
# range(4) resolved to 0, 1, 2, 3
if (i % 2 == 0): ip_list[i] += "-" # if i is even number - concatenate hyphen to the current IP string
else: ip_list[i] += "," # otherwize concatenate comma
print("".join(ip_list)[:-1]) # "".join(ip_list) - join the list back to a string
# [:-1] trim the last character of the result (the extra comma)

Categories