Introduction To “List”
--
What is a “List”?
- “Python Lists” are the “Sequences of Objects”.
- Unlike “String”, the “Python Lists” are “Mutable”. That means, the “Existing Elements” within the “Lists” can be “Replaced” or “Removed”, and, “New Elements” can be “Inserted” or “Appended” to the “Lists”.
How “Python Lists” are “Created”?
- “Python Lists” are “Delimited” by “Square Brackets”, i.e., “[]”.
- The “Items” within the “Lists” are “Separated” by “Commas”, i.e., “,”.
Create a “Heterogeneous List”
- “Python Lists” can be “Heterogeneous”. That means “Each” of the “Elements” inside a “Python List” can be of “Different Data Types”.
Create an “Empty List”
- It is possible to “Create” an “Empty List” by using an “Empty Square Brackets”.
Create a “List” From “Other Collection Data Types”
- “Python Lists” can be “Created” from “Other Collection Data Types”, such as — “Strings”, using the “list () Constructor”.
“Whitespace Rule” in “Python”
- The significant “Whitespace Rule” in “Python” can at first seem “Very Rigid”, but, there is a “Lot of Flexibility”.
- The “Whitespace Rule” states that if at the “End” of a “List Declaration Line”, the “Brackets”, “Braces”, or, “Parentheses” are “Unclosed”, it is possible to “Continue Declaring the List On the Next Line”. This can be “Very Useful” for “Long Literal Collections”, or, simply to “Improve” the “Readability”.
- It is allowed to use an “Additional Comma After the Last Element” in a “List Declaration”.
- This is an important “Maintainability Feature”.
“Retrieve Elements” From a “List”
- It is possible to “Retrieve” the “Elements” of a “List” by using the “Square Brackets”, i.e., “[]”, with a “Zero-Based Index”.
- Example — To “Retrieve” the “First Element” of a “List”, “[0]” should be used, to “Retrieve” the “Second Element” of a “List”, “[1]” should be used, and so on.
If the “List Index” of the “Element” to be “Retrieved” from a “List” is “Not Present” in the “List”, the “IndexError Exception” is “Thrown”.
“Negative Indices” in “Python List”
- One “Very Convenient Feature” of “Lists”, and, “Other Python Sequences”, such as — “Tuples”, and, “Strings”, is the “Ability” to “Index From the End”, as well as the “Ability” to “Index From the Beginning”. This is “Achieved” by “Supplying” the “Negative Indices”.
- It is possible to “Access” the “Last Element” of a “Python List” using the “Negative Index” as “-1”, the “Second Last Element” of a “Python List” using the “Negative Index” as “-2”, and, so on.
- The “Negative Indices” approach is “Much More Elegant” than the “Clunky Approach” of “Subtracting 1 From the Length of the Container”, which is otherwise used for “Retrieving the Last Element” in “Other Programming Languages”.
“Indexing” with “-0” is the “Same” as “Indexing” with “0”, which “Returns” the “First Element” in a “Python List”, because, there is “No Distinction” between “0” and “-0”, since the “Negative Indexing” is essentially “1-Based”, rather than “0-Based”.
This is good to keep in mind if the “Indices” are calculated with “Moderately Complex Logic”, because, “One-Off Errors” can “Creep Into” the “Negative Indexing” fairly easily.
“Slicing” in “Python List”
- “Slicing” is a “Form” of “Extended Indexing”, which allows to “Refer” to a “Portion of a Python List”.
- To use “Slicing”, the “Start Index”, and, the “Stop Index” of a “Half-Open Range”, that are “Separated” by a “Colon”, i.e., “:”, needs to be “Passed” as the “Square Brackets Index Argument”.
- The “Stop Index” should always be “1 Beyond the End of the Returned Range” as “Slicing” involves “Half-Open Range”.
- In the below example, the “Stop Index” is “2”, which is “1 Beyond the End of the Returned Range”, as the “Indices” of the “First Element” and “Second Element” are “0” and “1” respectively.
“Slicing” Facility can be “Combined” with the “Negative Indices” as well.
The “Negative Index” is used as the “Stop Index”.
Example — To “Take All the Elements Except the First and the Last” from a “Python List”, the “Slice” should be used as “[1:-1]”.
In “Slicing”, providing the “Negative Index” as the “Start Index” will “Return” an “Empty List”.
In “Slicing”, both the “Start” and “Stop Indices” are “Optional”.
To “Slice” “All” the “Elements”, from a particular “Start Index” to the “End” of the “Python List”, “No Number” should be “Put After” the “Colon”, i.e., “:”.
To “Slice” “All” the “Elements”, from the “Beginning” of a “Python List” “Upto” but “Not Including” a particular “Stop Index”, “No Number” should be “Put Before” the “Colon”, i.e., “:”.
Since in “Slicing”, both the “Start” and “Stop Indices” are “Optional”, it is entirely possible to “Omit” both of the “Start” and “Stop Indices”, and, “Retrieve” “All the Elements” of a “Python List”.
“Count” the “Number of Elements” of a “Python List”
- It is possible to “Determine” the “Number of Elements” in a “List” using the “Python Built-In Function”, i.e., “len ()”.
“Iterating Over” the “Elements” of “Python List”
- Since “Python Lists” are “Iterables”, the “for Loop” can be used to “Iterate Over” the “Elements” of “Python Lists”.
“Add Elements” Into a “Python List”
A. How “New Elements” Can Be “Added” To The “End” of a “Python List”?
- It is possible to “Add” the “New Element” to the “End” of a “Python List” by using the “append ()” Method.
- The “append ()” Method “Takes” “Only One Argument”. Hence, it is possible to “Add” “Only One New Element” to the “End” of a “Python List”.
However, it is possible to “Add” “More Than One New Elements” to the “End” of a “Python List”, if “All” the “New Elements” are “Passed” as a “New Iterable Series” altogether.
B. How “New Elements” Can Be “Inserted” At a “Particular Index” of a “Python List”?
- It is possible to “Insert” the “New Element” at a “Particular Index” of a “Python List” by using the “insert ()” Method.
- The “insert ()” Method “Accepts” the following “Two Arguments” -
1. The “Index” of the “New Element” to be “Inserted”.
2. The “New Element” itself.
- If the “List Index”, where the “New Element” needs to be “Inserted” into a “List”, using the “insert ()” Method, is “Not Present” in the “List”, the “New Element” will be “Appended” to the “End” of the “List”.
How “Existing Elements” From a “Python List” Can Be “Replaced” With “New Elements”?
- It is possible to “Replace” an “Existing Element” of a “Python List” with a “New Element” by “Assigning” the “New Element” to the “Index Position” of the “Desired Element” to be “Replaced”.
How “Existing Elements” From a “Python List” Can Be “Copied” Into “Another Python List”?
Shallow Copy
- A “Shallow Copy” is a “Technique” that “Creates” a “New List”, which “Contains” the “Same Object References” as the “Source List”, but, “Does Not Copy” the “Actual Reffered To Objects”.
- “Copying Lists” is “Shallow” by default, i.e., “Copying” only the “References” to the “List Elements”, and, “Not” the “List Elements”.
A. “Copy” an “Already Existing Python List” into a “New Python List” Using “Assignment”
- “Assigning” a “New Reference” to the “Reference” of an “Already Existing Python List” “Never Copies” the “Actual List Object”, but, merely “Copies” the “Reference” to that “Already Existing Python List Object”.
B. “Copy” an “Already Existing Python List” into a “New Python List” Using “Full Slicing”
- The “Full Slicing” of a “List”, i.e., “Omitting” both of the “Start” and “Stop Indices”, and, “Retrieving” “All the Elements” of a “Python List” needs to be “Performed” to “Copy” that “Existing Python List” to a “New Python List”.
- This “Creates” a “New Python List Object” with a “Distinct Identity”.
- It is important to understand that although the “Elements” of the “New Python List Object” can be “Independently Modified”, the “Elements” within it are the “References” to the “Same Objects”, which are “Referred To” by the “Original Python List Object”.
C. “Copy” an “Already Existing Python List” into a “New Python List” Using “copy ()” Method
- The “copy ()” Method is “Called On” the “Existing Python List” to “Copy” “All the Elements” of that “Existing Python List” to a “New Python List”.
D. “Copy” an “Already Existing Python List” into a “New Python List” Using “list () Constructor”
- “All the Elements” of an “Existing Python List” can be “Copied” into a “New Python List” by “Passing” the “Existing Python List” to the “list () Constructor”.
Although, it is a “Matter of Taste”, still it is “Preferrable” to use the “list () Constructor” approach to “Copy” “All the Elements” of an “Already Existing Python List” into a “New Python List”, since, this approach has the “Advantage” of “Working” with “Any Iterable Series” as the “Source”, and, “Not Just Lists”.
“Lists” with “Immutable Objects”
If the “List Elements” are “Immutable Objects”, such as — “String”, “Int”, “Tuple” etc., then after “Re-Binding”, i.e., “Replacing” “Any” of the “Values” that is present at “Any Index” in “Any” of the “List References”, the “Object” that is “Referred To” by the “Changed List Reference” at the “Index Position”, where “New Value” is “Replaced”, and, the “Object” that is “Referred To” by the “Unchanged List Reference” at the “Same Index Position”, where “Old Value” still “Remains” are “Not Same”.
If the “List Elements” are “Immutable Objects”, such as — “String”, “Int”, “Tuple” etc., then after “Mutating”, i.e., “Appending” “Any New Value” to the “End” of “Any” of the “List References”, or, “Inserting” “Any New Value” at a particular “Index” of “Any” of the “List References”, the “Object” that is “Referred To” by the “Changed List Reference” at that particular “Index Position”, where “New Value” is “Appended”, or, “Inserted”, and, the “Object” that is “Referred To” by the “Unchanged List Reference” at the “Same Index Position”, where “Old Value” still “Remains” are “Not Same”.
“Lists” with “Mutable Objects”
If the “List Elements” are “Mutable Objects”, such as — “List” itself, then after “Re-Binding”, i.e., “Replacing” “Any” of the “Inner List” that is present at “Any Index” in “Any” of the “Outer List References”, the “Object” that is “Referred To” by the “Changed Outer List Reference” at the “Index Position”, where “New Inner List” is “Replaced”, and, the “Object” that is “Referred To” by the “Unchanged Outer List Reference” at the “Same Index Position”, where “Old Inner List” still “Remains” are “Not the Same”.
If the “List Elements” are “Mutable Objects”, such as — “List” itself, then after “Mutating”, i.e., “Appending” “Any New Inner List” to the “End” of “Any” of the “Outer List References”, or, “Inserting” “Any New Inner List” at a particular “Index” of “Any” of the “Outer List References”, the “Object” that is “Referred To” by the “Changed Outer List Reference” at that particular “Index Position”, where “New Inner List” is “Appended”, or, “Inserted”, and, the “Object” that is “Referred To” by the “Unchanged Outer List Reference” at the “Same Index Position”, where “Old Inner List” still “Remains” are “Not the Same”.