It seems sometimes this call to swap works and sometimes the return data doesn't change the array.
It seems to work with the smaller array but not the bigger one.
data = [1, 4, 5, 3, 2]
data = [1, 4, 5, 3, 2, 88, 92, 68, 22, 7,
6, 11, 44, 56, 99, 31, 32, 66, 55,
44, 77, 92, 24, 27, 14, 17, 18, 51,
69, 61, 51, 82, 84, 14, 15, 60, 70]
def Swap(a, b):
temp = a
a = b
b = temp
return {a, b}
def BubbleSort(data):
for i in range(0, len(data)-1):
for j in range(0, len(data)-1):
if data[j] > data[j+1]:
(data[j], data[j+1]) = Swap(data[j], data[j+1])
print("In data: ", data)
print("Before data: ", data)
BubbleSort(data)
print("After data: ", data)
Your Swap function returns a set, the order of which is unspecified ( implementation-defined). You probably want to return a tuple (return (a, b) or, omitting the redundant parentheses, return a, b).
But the function is unnecessary anyway. The canonical way for swapping two values in Python is
a, b = b, a
The Swap function returns a set, which has no defined order. Therefore, it is not guaranteed that it actually has the effect of swapping two items.
You probably meant to return a tuple, which is written as (a, b) or simply a, b.
Also, it is not necessary in Python to use a temporary variable to swap two values, due to tuple assignment.
The canonical way to write a swap function in Python is:
def swap(a, b):
return b, a
Note also the lower-case function name which follows the official PEP-8 style guide.
Related
I want to make a function that would construct Lucas- (or Fibonacci-) like sequence. I want to be able to choose two first numbers and then to make the next one be a sum of two previous ones. The way I was thinking about that problem was:
def lucaslike(a, b, n):
x = [a, b]
for i in range(2, n+1):
return x.append(x[i-1] + x[i-2])
But when trying to use it print(lucaslike(3, 6, 10)), I get that the function is not defined.
I would like to be able to tell the function to produce Lucas-like sequence of n=10 terms, when for example two first values are a=3 and b=6. So that the output should be: [3, 6, 9, 15, 24, 39, ...].
You can change your code like this :
def lucaslike(a, b, n):
x = [a, b]
for i in range(2, n+1):
x.append(x[i-1] + x[i-2])
return x
Like that, this function will return only at the end the whole list of Lucas_like sentence.
lucaslike(3,6,10) or print(lucaslike(3,6,10)) will return [3, 6, 9, 15, 24, 39, 63, 102, 165, 267, 432]
I have a generator function generate which yields 5 random numbers one at a time. I need to be able to generate the numbers in two ways:
Single generation, which means a single output of generate function
Multiple generation, which means multiple execution of generate and yielding all the results together as a single (merged) flow
For that I wrote another function get_resource, which calls generate either once or using itertools.chain to run the generators one after another, but transparently to the caller.
My goal is to use get_resource function and produce the results in the same format (one list of numbers), regardless of single/multiple generations.
import itertools
import random
def get_resource(values=None):
def resource_generator():
if values:
# run a generator for every value
return itertools.chain(generate(value) for value in values)
else:
return generate('meh')
return resource_generator()
def generate(value):
for _ in range(5):
yield random.randint(1, 101)
if __name__ == '__main__':
# list() is used for convenience only,
# I still need the values one by one
print list(get_resource())
print list(get_resource([1, 2, 3]))
It prints:
[63, 22, 87, 2, 54]
[<generator object generate at 0x1089f7640>, <generator object generate at 0x1089f7690>, <generator object generate at 0x1089f76e0>]
While I need it to print:
[63, 22, 87, 2, 54]
[63, 22, 87, 2, 54, 1, 58, 79, 89, 77, 94, 99, 30, 30, 4]
I use python2.7
You can specify generator delegation using yield from starting with python-3.3+.
def get_resource(values=None):
def resource_generator():
if values:
for value in values:
yield from generate(value)
else:
yield from generate(None)
return resource_generator()
Now,
>>> list(get_resource([1, 2, 3]))
[46, 99, 97, 1, 42, 79, 69, 9, 45, 25, 77, 56, 54, 7, 41]
you should use itertools.chain.from_iterable
return itertools.chain.from_iterable(generate(value) for value in values)
I couldn't find a solution to the following problem:
I am trying to find the minimum in a C++ array, but without looking at all elements inside, only among elements that have a specified index.
E.g., if I am given an index k, and an array int* mylist = int[n], then I want to look for the minimal element in mylist only in a "sublist" of elements, where e.g. the index of the respective elements i fulfills i%n = k.
In Python, this can be easily solved by
min([mylist[i] for i in range(n) if i%n==k]),
but afaik, there is no equivalent in C++. Also, lambda functions do not do the trick, as far as I understood.
Any idea how to do this efficiently? Any advice would be appreciated!
This is an example of why standard algorithms work with iterators rather than directly with containers/collections. It allows you to write an iterator that embodies the indices you care about.
The problem is that writing an iterator is more work than most people would like, or consider justified for this simple of a task. Boost has some utilities to make it easier to implement iterators, such as a filter iterator, but as far as I know these are applied based only on the content of the collection, not the indices.
The code involved in creating an index_filter would be fairly trivial (e.g., should be easy to extrapolate from the code for filter_iterator linked above), but there's more boiler-plate there than most people would like. Unless you're doing things like this pretty regularly, it may be difficult to justify.
With range-v3, you may do something similar to:
for (auto e : v | ranges::view::drop(3) | ranges::view::stride(5)) {
std::cout << e << std::endl;
}
so you iterate over index 5 * k + 3.
And you can call ranges::min_element on resulting view:
auto view = v | ranges::view::drop(3) | ranges::view::stride(5);
auto it = ranges::min_element(view);
std::cout << *it << std::endl;
Demo
i % n = k will be a either:
k if k < n
[] empty that is, if k > n
This is because i varies from 0 to n
Hence there will be only one or no elements.
For clarity: n = 50; print([i%n for i in range(n)]) , gives:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
That is, unique values between 0 to n-1
So I have this list and variables:
nums = [14, 8, 9, 16, 3, 11, 5]
big = nums[0]
spot = 0
I'm confused about how to actually do it. I want to use this exercise to give me a starter. How do I do that on Python?
Usually, you could just use
max(nums)
If you explicitly want to use a loop, try:
max_value = None
for n in nums:
if max_value is None or n > max_value: max_value = n
Here you go...
nums = [14, 8, 9, 16, 3, 11, 5]
big = max(nums)
spot = nums.index(big)
This would be the Pythonic way of achieving this. If you want to use a loop, then loop with the current max value and check if each element is larger, and if so, assign to the current max.
nums = [14, 8, 9, 16, 3, 11, 5]
big = None
spot = None
for i, v in enumerate(nums):
if big is None or v > big:
big = v
spot = i
Python already has built in function for this kind of requirement.
list = [3,8,2,9]
max_number = max(list)
print (max_number) # it will print 9 as big number
however if you find the max number with the classic vay you can use loops.
list = [3,8,2,9]
current_max_number = list[0]
for number in list:
if number>current_max_number:
current_max_number = number
print (current_max_number) #it will display 9 as big number
Why not simply using the built-in max() function:
>>> m = max(nums)
By the way, some answers to similar questions might be useful:
Pythonic way to find maximum value and its index in a list?
How to find all positions of the maximum value in a list?
To address your second question, you can use a for loop:
for i in range(len(list)):
# do whatever
You should note that range() can have 3 arguments: start, end, and step. Start is what number to start with (if not supplied, it is 0); start is inclusive.. End is where to end at (this has to be give); end is exclusive: if you do range(100), it will give you 0-99. Step is also optional, it means what interval to use. If step is not provided, it will be 1. For example:
>>> x = range(10, 100, 5) # start at 10, end at 101, and use an interval of 5
>>> x
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] # note that it does not hit 100
Since end is exclusive, to include 100, we could do:
>>> x = range(10, 101, 5) # start at 10, end at 101, and use an interval of 5
>>> x
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100] # note that it does hit 100
For the Max in List Code HS I've managed to get most of the auto grader to work for me using this code:
list = [-3,-8,-2,0]
current_max_number = list[0]
for number in list:
if number>current_max_number:
current_max_number = number
print current_max_number
def max_int_in_list():
print "Here"
I'm not sure where the max_int_in_list goes though. It needs to have exactly 1 parameter.
To print the Index of the largest number in a list.
numbers = [1,2,3,4,5,6,9]
N = 0
for num in range(len(numbers)) :
if numbers[num] > N :
N = numbers[num]
print(numbers.index(N))
student_scores[1,2,3,4,5,6,7,8,9]
max=student_scores[0]
for n in range(0,len(student_scores)):
if student_scores[n]>=max:
max=student_scores[n]
print(max)
# using for loop to go through all items in the list and assign the biggest value to a variable, which was defined as max.
min=student_scores[0]
for n in range(0,len(student_scores)):
if student_scores[n]<=min:
min=student_scores[n]
print(min)
# using for loop to go through all items in the list and assign the smallest value to a variable, which was defined as min.
Note: the above code is to pick up the max and min by using for loop, which can be commonly used in other programming languages as well. However, the max() and min() functions are the easiest way to use in Python to get the same results.
I would add this as a reference too. You can use the sort and then print the last number.
nums = [14, 8, 9, 16, 3, 11, 5]
nums.sort()
print("Highest number is: ", nums[-1])
scores = [12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27,
28, 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 31, 31, 37,
56, 75, 23, 565]
# initialize highest to zero
highest = 0
for mark in scores:
if highest < mark:
highest = mark
print(mark)
This question already has answers here:
Why do these list methods (append, sort, extend, remove, clear, reverse) return None rather than the resulting list?
(6 answers)
Closed 6 months ago.
Second list squared each item on list, xs. Running the code below, python gives me 'None'
xs = [12, 10, 32, 3, 66, 17, 42, 99, 20]
a = [b**2 for b in xs]
c = (a + xs).sort()
print(c, end=', ')
Same list but different code--
xs = [12, 10, 32, 3, 66, 17, 42, 99, 20]
a = [b**2 for b in xs]
c = a + xs
c.sort()
print(c, end=', ')
...python gives me my list(c), all sorted. I don't get it. Or is there a more pythonic way to do this?
Thanks!
Generally speaking, anything that operates on something in-place will return None, by convention. (This convention is not necessarily always followed, however.) somelist.sort() will sort the list in-place.
If you'd rather have a sorted copy, you can just call c = sorted(a + xs). sorted operates on a copy of the original, and therefore returns the copy.
There's a much more through explanation here: http://wiki.python.org/moin/HowTo/Sorting/
You use generator expressions and itertools to reduce the amount of temporary storage like this
>>> import itertools
>>> xs = [12, 10, 32, 3, 66, 17, 42, 99, 20]
>>> a = (b**2 for b in xs)
>>> c = sorted(itertools.chain(a, xs))
>>> c
[3, 9, 10, 12, 17, 20, 32, 42, 66, 99, 100, 144, 289, 400, 1024, 1764, 4356, 9801]