I have recently been perplexed by some of the behavior of sprintf. It appears to be inconsistent in my view and I haven't been able to exactly determine the logic behind some of its behavior. Here is one case that baffles me
C = [1 + 2i, 3+ 4i, 5+6i, 7+8i, 9+10i];
>> sprintf('%+d%+di\n',real(C(1:2)),imag(C(1:2)))
ans =
+1+3i
+2+4i
>> sprintf('%+d%+di\n',real(C(1:3)),imag(C(1:3)))
ans =
+1+3i
+5+2i
+4+6i
I would've expected it to print my complex numbers as in C. Do I need to explicitly create a new vector of interleaved inputs? I feel this is problematic when different types are involved.
EDIT: What I feel the expected output should be
>> sprintf('%+d%+di\n',real(C(1:2)),imag(C(1:2)))
ans =
+1+2i
+3+4i
>> sprintf('%+d%+di\n',real(C(1:3)),imag(C(1:3)))
ans =
+1+2i
+3+4i
+5+6i
The sprintf command you have provided behaves as sprintf('%+d%+di\n', [1, 3], [2, 4]) since real(C(1:2)) returns [1, 3] and imag(C(1:2)) returns [2, 4] which behaves as you've observed.
What you want to do is: sprintf('%+d%+di\n', [1, 3; 2, 4])
It should be accomplished by either looping over elements of C or with the following sprinf('%+d%+di\n', [real(C(1:2)); imag(C(1:2))]).
Related
I am trying to sort an unsorted list [4, 5, 9, 9, 0, 1, 8]
The list has two repeated elements. I have tried to approach the question by having a loop that goes through each element comparing each element with the next in the list and then placing the smaller element at the start of the list.
def sort(ls:
ls[x]
x = [4, 5, 9, 9, 0, 1, 8]
while len(x) > 0:
for i in the range(0, len(x)):
lowest = x[i]
ls.append(lowest)
Please, could someone explain where I am going wrong and how the code should work?
It may be that I have incorrectly thought about the problem and my reasoning for how the code should work is not right
I do not know, if this is exactly what you are looking for but try: sorted(ListObject).
sorted() returns the elements of the list from the smallest to the biggest. If one element is repeated, the repeated element is right after the original element. Hope that helped.
Yes, you can try x.sort() or sorted(x). Check this out https://www.programiz.com/python-programming/methods/built-in/sorted. Also, in your program I don't see you making any comparisons, for example, if x[i] <= x[i+1] then ...
This block of code is just gonna append all the elements in the same order, till n*n times.
Also check this https://en.wikipedia.org/wiki/Insertion_sort
For a built-in Python function to sort, let y be your original list, you can use either sorted(y) or y.sort().Keep in mind that sorted(y) will return a new list so you would need to assign it to a variable such as x=sorted(y); whereas if you use x.sort() it will mutate the original list in-place, so you would just call it as is.
If you're looking to actually implement a sorting function, you can try Merge Sort or Quick Sort which run in O (n log n) in which will handle elements with the same value. You can check this out if you want -> https://www.geeksforgeeks.org/python-program-for-merge-sort/ . For an easier to understand sorting algorithm, Insertion or Bubble sort also handle duplicate as well but have a longer runtime O (n^2) -> https://www.geeksforgeeks.org/python-program-for-bubble-sort/ .
But yea, I agree with Nameet, what you've currently posted looks like it would just append in the same order.
Try one of the above suggestions and hopefully this helps point you in the right direction to if you're looking for a built-in function or to implement a sort, which can be done in multiple ways with different adv and disadv to each one. Hope this helps and good luck!
There are several popular ways for sorting. take bubble sort as an example,
def bubbleSort(array):
x = len(array)
while(x > 1): # the code below make sense only there are at least 2 elements in the list
for i in range(x-1): # maximum of i is x-2, the last element in arr is arr[x-1]
if array[i] > array[i+1]:
array[i], array[i+1] = array[i+1], array[i]
x -= 1
return array
x = [4, 5, 9, 9, 0, 1, 8]
bubbleSort(x)
your code has the same logic as below
def sorts(x):
ls = []
while len(x) > 0:
lowest = min(x)
ls.append(lowest)
x.remove(lowest)
return ls
x = [4, 5, 9, 9, 0, 1, 8]
sorts(x)
#output is [0, 1, 4, 5, 8, 9, 9]
I'm fairly new to coding in the python3 language. I'm trying to construct a function that takes two vectors and subtracts them. Any help would be great. Thank you in advance.
Write a function vecSubtract(vector01, vector02) which takes in two vectors as arguments, and returns the vector which is equal to vector01-vector02.
def vecSubtract(vector01,vector02):
for i in range(min(len(vector01), len(vector02))):
result = [vector01[i]-vector02[i] ]
return result
vector01 = [3, 3, 3]
vector02 = [4, 4, 4]
print(vecSubtract(vector01,vector02))
While you are looping over the vectors (lists actually), you are overwriting your result variable every time.
You probably want to use a list comprehension instead.
def vecSubtract(vector01, vector02):
result = [vector01[i] - vector02[i] for i in range(min(len(vector01), len(vector02)))]
return result
vector01 = [3, 3, 3]
vector02 = [4, 4, 4]
print(vecSubtract(vector01,vector02))
If you really want to use a for loop, you should use result.append() instead of overwriting the variable every time.
Also, it is probably not right to allow subtraction of vectors of different lengths by ignoring the surplus elements in the longer vector. Instead you should probably test that the two vectors are the same length and have the script throw an error if they are not.
I have:
AB_xy = [4, 3, 5, 9, 10]
And I want to access AB_xy elements by combining its name from two separate strings something like this:
['AB' '_xy'](1)
I would like this to return 4 as it would be done by AB_xy(1)but this doesnt work. Suggestions ?
Here, eval would work, if you also include the index
AB_xy = [4, 3, 5, 9, 10];
eval(['AB', '_xy(1)'])
ans =
4
But in general eval should be avoided as there are other alternatives.
Perhaps you could consider making AB a struct with xy as a field.
AB.xy = [4, 3, 5, 9, 10];
and use dynamic field reference
str = 'xy';
AB.(str)(1)
ans =
4
It sounds lika an eval problem.
s = strcat('AB', '_xy', '(', '1', ')')
eval(s)
Of course, just substitute the strings in strcat to variables holding the string(s) you would like to concatenate.
And I agree fully with #BillBokeey. eval is usually a code smell.
How do you check whether an element is already in the list when I am doing it in comprehension?
For example say in following comprehension I want to restrict duplicate numbers Though I am not looking for unique number at all, I want to prevent via an if condition.
[x for x in [1,2,3,1,2,3]]
I am looking for something like
[x for x in [1,2,3,1,2,3] if not in self]
I think what you are looking for is set comprehension and conversion to list. It would do what you want without any odd syntax.
ans = list({x for x in [1,2,3,1,2,3])})
Actaully that can be also be simplified to
ans = list(set([1,2,3,1,2,3]))
but I think the first one might be better in performance.
You can't access the comprehension as you're creating it (as far as I know; someone please correct me if I'm wrong!), but in your case you can just use a set, which eliminates duplicates.
uniques = set([1, 2, 3, 1, 2, 3])
print(uniques) # >>> set([1, 2, 3])
If your list comprehension needs to be more complex, you can index the comprehension from the set, rather than the original list.
mylist = [1, 2, 3, 1, 2, 3]
print([x*x for x in set(mylist)]) # >>> [1, 4, 9]
If you really need direct access to the list during creation, you need to use an explicit loop rather than a comprehension.
x = [1,2,3,1,2,3]
y = [x[n] for n in range(len(x)) if x.index(x[n]) == n]
?
I think at this point, it's probably more readable to simply write it using a for-loop rather than a comprehension.
The following Groovy code
lines = ['0','1','2','3','4','5']
println lines[1..lines.size()-1]
println lines[1..-1]
println lines[1..<lines.size()-1]
println lines[1..<-1]
println lines[1..<-2]
println lines[1..-2]
produces this output:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
[1, 0]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
Since -1 is the index of the last element in the list, the first two make sense (ranges in Groovy include the end element instead of omitting it as everywhere else in Java :-( )
Line #3 is the desired output (list without first and last element).
I'm worried about the output #4: Why do I get [1, 0] for 1..-1?
Also [1, 2, 3, 4, 5] for the range 1..<-2 seems wrong.
Why does that happen?
The best way to take all elements but the last one, in my opinion, is to use the take method:
def list = ['a', 'b', 'c']
assert list.take(list.size() - 1) == ['a', 'b']
It behaves properly in the corner case where size == 1:
def list = ['one']
assert list.take(list.size() - 1) == []
Though I'd prefer it to throw an exception in the case size == 0, but the behavior is not that bad:
def list = []
assert list.take(list.size() - 1) == []
You can also use list[0..<list.size()-1] (your third example) and it will behave the same except for the empty list, in which case it will throw an ArrayIndexOutOfBoundsException, but i think is not as readable as the take counterpart.
Another acceptable solution is using list[0..-2] (your last example), which i think looks much more elegant, but unfortunately breaks when size == 1 with an ArrayIndexOutOfBoundsException.
In your examples (i'll assume that you meant to use 0 as the starting index instead of 1 if you wanted to include all elements but the last one):
lines[0..lines.size()-1] is equivalent to lines[0..-1] because the getAt(Range) method of lists will treat ranges with negative indexes the same way asgetAt(Integer) does, i.e. as accessing the (list.size() + negativeIndex)'th element of the list. Therefore list[0..-1] is the same as saying "from first element to last" and it's the same as copying the list; and list[-1..0] is the same as "from last to first" and it's equivalent to list.reverse() :)
The problem with the other non-inclusive range example is that the non-inclusive ranges are being evaluated before the list access and they evaluate to an incorrect inclusive range. For example, 0..<-2 evaluates to 0..-1, and that's why it's returning all the elements. 0..<-1 evaluates to 0..0 and it returns only the first element.
Notice that the empty range is a special case. It's denoted as 0..<0 and it doesn't have an inclusive equivalent (so Groovy won't do any magic conversion here). And that's why list[0..<list.size()-1] works when size == 1 (the range evaluates to the empty range) while list[0..-2] doesn't :)
Maybe this has changed since epideman wrote his answer, but you can get the whole list without the last element with 0..<-1:
assert ["foo"][0..<-1] == []
assert ["foo", "bar"][0..<-1] == ["foo"]
assert ["foo", "bar", "baz"][0..<-1] == ["foo", "bar"]
// blows up if empty, here take is better
assert [][0..<-1] == [] // BOOM
// if you want null safe, use take
assert [].take(-1) == []
This is with groovy 2.2.1.
Since Groovy 2.4 you can use the init() method:
lines = ['0','1','2','3','4','5']
assert lines.init() == ['0','1','2','3','4']