Lists in Python A versatile data structure used to store multiple items in a single variable. 🎯 1. What is a List? Lists are ordered, mutable collections of items that allow duplicate elements. They are defined using square brackets []. 🎯 2. Creating a List A list by placing comma-separated values inside square brackets. python # Example my_list = [1, "Hello", 3.14, True] 🎯 3. Accessing List Elements & Indexing zero-based indexing to access elements. python # Example fruits = ["apple", "banana", "cherry"] print(fruits[0]) # First element print(fruits[-1]) # Last element 🎯 4. List Slicing Access a range of elements Syntax [start:stop:step]. python # Example numbers = [10, 20, 30, 40, 50, 60] print(numbers[1:4]) # From index 1 up to (but not including) 4 print(numbers[::-1]) # Reverse the list Output: [20, 30, 40] [60, 50, 40, 30, 20, 10] 🎯 5. Modifying Lists Lists are mutable, meaning you can change their items. python # Example fruits = ["apple", "banana", "cherry"] fruits[1] = "blueberry" # Change index 1 print(fruits) Output: [apple, blueberry, cherry] 🎯 6. List Methods append() : Adds an item to the end. python fruits.append("orange") insert() : Adds an item at a specific position. python fruits.insert(1, "mango") remove() : Removes the first occurrence of a specific value. python fruits.remove("banana") pop() : Removes and returns an item at a specific index (or the last item if no index is specified). python last_item = fruits.pop() sort() : Sorts the list in place. 🎯 List Comprehensions A list comprehension offers a concise way to create lists in Python based on existing lists or iterables. Basic Syntax: new_list = [expression for item in iterable if condition] 🎯 1. Creating a List of Squares Instead of using a for loop to append squares, you can do it in one line. python # Traditional loop squares = [] for x in range(1, 6): squares.append(x*2) 🎯 List comprehension squares = [x*2 for x in range(1, 6)] print(squares) Output: [1, 4, 9, 16, 25] 🎯 2. Filtering with if Condition You can add a condition to filter elements from the original list. python numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Get only even numbers evens = [x for x in numbers if x % 2 == 0] print(evens) Output: [2, 4, 6, 8, 10] 🎯 3. Transforming Strings You can apply string methods like .upper() during creation. python fruits = ["apple", "banana", "cherry"] # Convert all to uppercase upper_fruits = [fruit.upper() for fruit in fruits] print(upper_fruits) Output: ['APPLE', 'BANANA', 'CHERRY'] 🎯 4. Flattening a Nested List This is a highly efficient way to turn a list of lists into a single flat list. python nested_list = [[1, 2], [3, 4], [5, 6]] # Flatten the list flatlist = [item for sublist in nestedlist for item in sublist] print(flat_list) Output: [1, 2, 3, 4, 5, 6] #PythonProgramming #PythonList #DataScience #CodingTips #PythonTutorial #SoftwareDevelopment #Programming
Python Lists: A Comprehensive Guide
More Relevant Posts
-
Day 11/30 - Python Dictionaries Today I learned the most powerful data structure in Python. And honestly it changed how I think about storing data. What is a Dictionary? A dictionary is an ordered, mutable collection of key-value pairs defined using curly braces {}. Unlike lists which use index numbers, dictionaries use keys , meaningful labels to access each value. Think of it like a real dictionary: you look up a word (key) to get its definition (value). Three core traits: Ordered — from Python 3.7+, dictionaries remember insertion order Mutable — you can add, update, and remove pairs after creation No duplicate keys — if you add the same key twice, the second value overwrites the first Syntax Breakdown my_dict = {"key1": value1, "key2": value2} "key" -> the label used to look up a value - must be unique and immutable value -> the data stored - can be any type: string, int, list, even another dict { } -> curly braces wrap the whole dictionary - pairs separated by commas Accessing Values dict.get("key") → returns None safely if the key is missing dict.get("key", "default") → returns your fallback value instead of None Rule: Use dict["key"] when you're sure the key exists. Use dict.get() when you're not — it's always the safer choice. Adding & Updating Items Add new key: dict["new_key"] = value Update existing key: dict["key"] = new_value Update multiple: dict.update({"key1": val, "key2": val}) Remove a key: dict.pop("key") Code Example student = { "name" : "Obiageli", "course": "Machine learning", "year" : 2024, "gpa" : 4.5 } print(student["name"]) =Obiageli print(student.get("gpa")) = 4.5 student["age"] = 22 student["gpa"] = 4.7 Key Learnings ☑ A dictionary stores data as key-value pairs. keys are labels, values are the data ☑ Use dict.get("key") over dict["key"] when unsure a key exists ☑ Keys must be unique and immutable — values can be any data type ☑ Use .keys(), .values(), .items() to loop through dictionaries effectively ☑ Dictionaries are the foundation of JSON — the format every web API sends data in Why It Matters Every time an app stores a user profile, an API sends data, or a program reads a config file, that data is almost always in dictionary format. Mastering dictionaries means you can work with real-world data right now. My Takeaway Lists store things in a line , dictionaries store things with meaning. Once I started thinking in key-value pairs, data started making a lot more sense. It's not just storage , it's structured storage. #30DaysOfPython #Python #LearnToCode #CodingJourney #WomenInTech
To view or add a comment, sign in
-
-
1: Everything is an object? In the world of Python, (an integer, a string, a list , or even a function) are all treated as an objects. This is what makes Python so flexible but introduces specific behaviors regarding memory management and data integrity that must be will known for each developer. 2: ID and type: Every object has 3 components: identity, type, and value. - Identity: The object's address in memory, it can be retrieved by using id() function. - Type: Defines what the object can do and what values could be hold. *a = [1, 2, 3] print(id(a)) print(type(a)) 3: Mutable Objects: Contents can be changed after they're created without changing their identity. E.x. lists, dictionaries, sets, and byte arrays. *l1 = [1, 2, 3] l2 = l1 l1.append(4) print(l2) 4: Immutable Objects: Once it is created, it can't be changed. If you try to modify it, Python create new object with a new identity. This includes integers, floats, strings, tuples, frozensets, and bytes. *s1 = "Holberton" s2 = s1 s1 = s1 + "school" print(s2) 5: why it matters? and how Python treats objects? The distinction between them dictates how Python manages memory. Python uses integer interning (pre-allocating small integers between -5 and 256) and string interning for performance. However, it is matter because aliasing (two variables pointing to the same object) can lead to bugs. Understanding this allows you to choose the right data structure. 6: Passing Arguments to Functions: "Call by Assignment." is a mechanism used by Python. When you pass an argument to a function, Python passes the reference to the object. - Mutable: If you pass a list to a function and modify it inside, the change persists outside because the function operated on the original memory address. - Immutable: If you pass a string and modify it inside, the function creates a local copy, leaving the original external variable untouched. *def increment(n, l): n += 1 l.append(1) val = 10 my_list = [10] increment(val, my_list) print(val) print(my_list) *: Indicates an examples. I didn't involve the output, you can try it!
To view or add a comment, sign in
-
-
• Day 30/30 Today I learned about Python File Handling Methods, which are used to work with files such as reading, writing, updating, and managing file content. File handling is very important because it allows us to store data permanently instead of keeping it only in memory while the program runs. 🔸 Common Python File Methods • open(): The close() method is used to close a file after use. It is important because it ensures that resources are released properly. file = open("sample.txt", "r") print(file) file.close() • read(): The read() method is used to read the entire content of a file at once. It is useful when we want to access all the text stored inside a file. with open("sample.txt", "r") as file: print(file.read()) • readline(): The readline() method reads one line at a time from the file. It is useful when working with large files. with open("sample.txt", "r") as file: print(file.readline()) • readlines(): The readlines() method reads all lines of a file and stores them in a list. Each line becomes a separate list element. This is helpful when we want to process file data line by line using loops. with open("sample.txt", "r") as file: print(file.readlines()) • write(): The write() method is used to write data into a file. If the file is opened in write mode, it will overwrite the existing content. This method is useful for saving text or program output into a file. with open("sample.txt", "w") as file: file.write("Hello Python") • writelines(): The writelines() method is used to write multiple lines into a file at once. It takes a list of strings and writes them to the file. This is useful when saving structured text data. lines = ["Python\n", "File Handling\n", "Methods\n"] with open("sample.txt", "w") as file: file.writelines(lines) • close(): The close() method is used to close a file after use. It is important because it ensures that resources are released properly. file = open("sample.txt", "r") file.close() print("File closed") • flush(): The readline() method reads one line at a time from the file. It is useful when working with large files. file = open("sample.txt", "w") file.write("Data saved") file.flush() file.close() • seek(): The flush() method forces the file buffer to write data immediately into the file without closing it. This is useful when we want to ensure that the data is saved instantly. with open("sample.txt", "r") as file: file.seek(0) print(file.read()) • tell(): The seek() method is used to move the file pointer to a specific position. This allows us to read or write from a particular point in the file. It is useful for random file access. print(file.tell()) When opening a file, Python uses different modes depending on the operation: "r" → Read mode "w" → Write mode "a" → Append mode "x" → Create mode "b" → Binary mode "t" → Text mode (default) #Python #File_Handling #BengaluruStudents #BangaloreIT #BTMLayout #fortunecloud Fortune Cloud Technologies Private Limited
To view or add a comment, sign in
-
-
🚀 Understanding Python Classes, Methods & self — With a Real Example If you're learning Python OOP, this example will make everything click 👇 🔹 The Code class DataValidator: def __init__(self): self.errors = [] def validate_email(self, email): if "@" not in email: self.errors.append(f"Invalid email: {email}") return False return True def validate_age(self, age): if age < 0 or age > 150: self.errors.append(f"Invalid age: {age}") return False return True def get_errors(self): return self.errors validator = DataValidator() validator.validate_email("bad-email") validator.validate_age(200) validator.validate_email("another-bad-email") validator.validate_age(150) print(validator.get_errors()) 🔹 Step-by-Step Explanation ✅ 1. Class (Blueprint) DataValidator is a class — a blueprint for creating validation objects. ✅ 2. Constructor (__init__) def __init__(self): self.errors = [] Runs automatically when object is created Initializes an empty list to store errors ✅ 3. Methods (Functions inside class) 👉 validate_email(self, email) Checks if email contains "@" If invalid → adds error to list 👉 validate_age(self, age) Checks if age is between 0 and 150 If invalid → stores error 👉 get_errors(self) Returns all collected errors 🔹 The Magic of self 💡 self = current object (instance) When you write: validator.validate_email("bad-email") Python internally does: DataValidator.validate_email(validator, "bad-email") 👉 That’s why we don’t pass self manually 🔹 Instance (Real Object) validator = DataValidator() This creates an object Each object has its own errors list 🔹 Output Explained ['Invalid email: bad-email', 'Invalid age: 200', 'Invalid email: another-bad-email'] ✔ Invalid email → no "@" ✔ Invalid age → 200 > 150 ✔ Valid age (150) → ignored 🔥 Key Takeaways Class = Blueprint 🏗️ Instance = Real object 🎯 Method = Action (function inside class) ⚙️ self = current object reference 🧠 Objects can store state (like errors list) 💬 This is how real-world systems validate data in forms, APIs, and apps. If you understand this, you're officially stepping into real OOP development 🚀 #Python #OOP #Programming #Coding #Developers #LearnToCode #SoftwareEngineering
To view or add a comment, sign in
-
Day 27 --Lambda Functions in Python Lambda Functions are small, anonymous functions that can be written in a single line. They are useful when you need a quick function for a short period of time and don’t want to formally define it using def. 🔹 Basic Syntax lambda arguments: expression 🔹 Example add = lambda a, b: a + b print(add(5, 3)) Output: 8 Here, the lambda function takes two arguments and returns their sum. 🔹 Using Lambda with map() map()--->The map() function is used to apply a specific function to every item in an iterable such as a list, tuple, or set. It returns a map object, so we usually convert it to a list to see the result. MAP SYNTAX:-map(function, iterable) function → the function you want to apply iterable → the list, tuple, or other collection of items EXAMPLE : Using Lambda with map() numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x**2, numbers)) print(squared) Output: [1, 4, 9, 16, 25] 🔹 Using Lambda with filter() FILTER()--->The filter() function is used to select elements from an iterable based on a condition. It returns only the elements that satisfy the condition. SYNTAX:-filter(function, iterable) function → a function that returns True or False iterable → the collection of items to filter EXAMPLE : Using Lambda with filter() numbers = [1, 2, 3, 4, 5, 6] even_numbers = list(filter(lambda x: x % 2 == 0, numbers)) print(even_numbers) Output: [2, 4, 6] EXAMPLE : Using Lambda with sorted() numbers =[1,2,3,4,5,6] sorted(numbers, key=lambda x:-x)# [6, 5, 4, 3, 2, 1] Key Points *Lambda functions are anonymous functions. *They are written in a single expression. *Commonly used with functions like map(), filter(), and sorted(). *Useful for short, simple operations. Learning concepts like this helps me understand how Python can write clean and concise code. Do you prefer lambda or regular def functions? Drop your answer below 👇 #Python #PythonLearning #CodingJourney #Programming
To view or add a comment, sign in
-
-
Python Prototypes vs. Production Systems: Lessons in Logic Rigor 🛠️ This week, I stopped trying to write code that "just works" and started writing code that refuses to crash. As an aspiring Data Scientist, I’m learning that stakeholders don’t just care about the output—they care about uptime. If a single "typo" from a user kills your entire analytics pipeline, your system isn't ready for the real world. Here are the 4 "Industry Veteran" shifts I made to my latest Python project: 1. EAFP over LBYL (Stop "Looking Before You Leap") In Python, we often use if statements to check every possible error (Look Before You Leap). But a "Senior" approach often favors EAFP (Easier to Ask for Forgiveness than Permission) using try/except blocks. Why? if statements become "spaghetti" when checking for types, ranges, and existence all at once. Rigor: A try block handles the "ABC" input in a float field immediately, keeping the logic clean and the performance high. 2. The .get() Method: Killing the KeyError Directly indexing a dictionary with prices[item] is a ticking time bomb. If the key is missing, the program dies. The Fix: I’ve switched to .get(item, 0.0). This allows for a "Default Value" fallback in a single line, preventing "Dictionary Sparsity" from breaking my calculations. 3. Preventing the "System Crush" Stakeholders hate downtime. I implemented a while True loop combined with try/except for all user inputs. The Goal: The program should never end unless the user explicitly chooses to "Quit." Every "bad" input now triggers a helpful re-prompt instead of a system failure. 4. Precision in Data Type Conversion Logic errors often hide in the "Conversion Chain." I focused on the transition from String (from input()) to Int (for indexing). The Off-by-One Risk: Users think in "1-based" counting, but Python is "0-based." I’ve made it a rule to always subtract 1 from the integer input immediately to ensure the correct data point is retrieved every time. The Lesson: Coding is about the architecture of the "Why" just as much as the syntax of the "What." [https://lnkd.in/gvtiAKUb] #Python #DataScience #CodingJourney #CleanCode #BuildInPublic #SoftwareEngineering #SeniorDataScientist #TechMentor
To view or add a comment, sign in
-
-
Python 3: Mutable, Immutable... Everything Is Object Python treats everything as an object. A variable is not a box that stores a value directly; it is a name bound to an object. That is why assignment, comparison, and updates can behave differently depending on the type of object involved. For example, a = 10; b = a means both names refer to the same integer object, while l1 = [1, 2]; l2 = l1 means both names refer to the same list object. Many Python surprises come from object identity and mutability. Two built-in functions are essential when studying objects: id() and type(). type() tells us the class of an object, while id() gives its identity in the current runtime. Example: a = 3; b = a; print(type(a)) prints <class 'int'>, and print(a is b) prints True because both names point to the same object. By contrast, l1 = [1, 2, 3]; l2 = [1, 2, 3] gives l1 == l2 as True but l1 is l2 as False. Equality checks value, but identity checks whether two names point to the exact same object. Mutable objects can be changed after they are created. Lists, dictionaries, and sets are common mutable types. If two variables reference the same mutable object, a change through one name is visible through the other. Example: l1 = [1, 2, 3]; l2 = l1; l1.append(4); print(l2) outputs [1, 2, 3, 4]. The list changed in place, and both names still point to that same list. Immutable objects cannot be changed after creation. Integers, strings, booleans, and tuples are common immutable types. If an immutable object seems to change, Python actually creates a new object and rebinds the variable. Example: a = 1; a = a + 1 does not modify the original 1; it creates 2 and binds a to it. The same happens with strings: s = "Hi"; s = s + "!" creates a new string. Tuples are also immutable: (1) is just the integer 1, while (1,) is a tuple. This matters because Python treats mutable and immutable objects differently during updates. l1.append(4) mutates a list in place, but l1 = l1 + [4] creates a new list and reassigns the name. With immutable objects, operations produce a new object rather than changing the existing one. That is why == is for value and is is for identity, especially checks like x is None. Arguments in Python are passed as object references. A function receives a reference to the same object, not a copy. That means behavior depends on whether the function mutates the object or simply rebinds a local name. Example: def add(x): x.append(4) changes the original list. But def inc(n): n += 1 does not change the caller’s integer because integers are immutable and the local variable is rebound. From the advanced tasks, I also learned that CPython may reuse some constant objects such as small integers and empty tuples as an optimization. That helps explain identity results, but it also reinforces the rule: never rely on is for value comparison when == is what you mean.
To view or add a comment, sign in
-
-
Python3: Mutable, Immutable… Everything is an Object! Introduction : In Python, everything is an object. This fundamental idea shapes how variables behave, how memory is managed, and how data flows through your programs. Understanding the difference between mutable and immutable objects is essential for writing predictable and efficient code. In this post, I’ll walk through object identity, types, mutability, and how Python handles function arguments—with concrete examples. Id and Type : Every Object in Python has: an identity (its memory address) - a type (what kind of object it is) - a value You can inspect these using id() and type(): x=10 print(id(x)) # unique identifier (memory address) print(type(x)) # <class 'int'> Example Output : 140734347123456 <class 'int'> Two variables can point to the same object: a = 5 b = a print(id(a)) print(id(b)) Both a and b will have the same id, meaning they reference the same object. MUTABLE OBJECTS : Mutable objects can be changed after they are created without changing their identity. Common mutable types: List , dict , set Example: my_list = [1, 2, 3] print(id(my_list)) my_list.append(4) print(my_list) print(id(my_list)) # same id! Output: [1, 2, 3, 4] The content changed, but the memory address stayed the same. Another example with dictionaries: d = {"a": 1} d["b"] = 2 print(d) # {'a': 1, 'b': 2} IMMUTABLE OBJECTS: Immutable objects cannot be modified after creation. Any "change" actually creates a new object. Common immutable types: int , float , str , tuple Example: x = 10 print(id(x)) x = x + 1 print(id(x)) # different id! Output: 140734347123456 140734347123999 A new object is created instead of modifying the old one. String example: s = "hello" print(id(s)) s += " world" print(id(s)) Again, a new object is created. Why does it matter? Understanding mutability helps avoid unexpected bugs. Example problem: list1 = [1, 2, 3] list2 = list1 list2.append(4) print(list1) # [1, 2, 3, 4] Both variables changed because they reference the same object. To avoid this: list2 = list1.copy() Now they are independent. HOW ARGUMENTS ARE PASSED TO FUNCTIONS Python uses pass-by-object-reference (or “call by sharing”). With immutable objects: def add_one(x): x += 1 print("Inside:", x) a = 5 add_one(a) print("Outside:", a) Output: Inside: 6 Outside: 5 The original value is unchanged. With mutable objects: def add_item(lst): lst.append(4) print("Inside:", lst) my_list = [1, 2, 3] add_item(my_list) print("Outside:", my_list) Output: Inside: [1, 2, 3, 4] Outside: [1, 2, 3, 4] The original object is modified. IMPORT IMPLICATION If you don’t want a function to modify your data: def safe_modify(lst): lst = lst.copy() lst.append(4) return lst Understanding mutable vs immutable objects is crucial in Python because it directly affects: memory behavior , variable assignment , function side effects
To view or add a comment, sign in
-
-
Day 9 of my Python journey — for loops. If while loops are about "keep going until done," for loops are about "do this for every item." This distinction matters because most real programming is about processing collections — lists of users, rows of data, records from a database, items in a cart. Today I focused not just on how for loops work, but on the patterns that make them professional. enumerate() — stop tracking indexes manually # Beginner approach — works but is not Pythonic for i in range(len(students)): print(f"{i+1}. {students[i]['name']}") # Professional approach for rank, student in enumerate(students, start=1): print(f"{rank}. {student['name']}") enumerate() gives you both the index and the value on every iteration. Using it instead of manual index tracking is one of the most visible signs of Python experience. Every code review at a professional company will flag the first approach as beginner code. zip() — iterate two related collections simultaneously names = ["Rahul", "Priya", "Arjun", "Neha"] scores = [87, 94, 72, 88] for name, score in zip(names, scores): status = "Pass" if score >= 40 else "Fail" print(f"{name:<10} | {score:>3} | {status}") zip() pairs corresponding elements from two lists and iterates them together. This pattern is used daily in data engineering: matching timestamps with values, pairing users with permissions, correlating products with prices. The three patterns that solve 80% of loop problems Accumulator: total = 0; for x in data: total += x Counter: count = 0; for x in data: if condition: count += 1 Collector: result = []; for x in data: if condition: result.append(x) Recognise the pattern first, then write the loop. This is what separates fast problem-solving from slow trial-and-error. Nested loops and cost awareness A loop inside a loop is O(n²). For 100 items that is 10,000 operations. For 1,000 items that is 1,000,000. I learned today to consciously choose when nesting is justified and when a different approach is needed. This thinking starts in Week 2, not Week 20. Every data processing job in Python depends on this. #Python#Day9#ConditionalLogic#SelfLearning#CodewithHarry#PythonBasics#w3schools.com#W3Schools
To view or add a comment, sign in
-
*🚀Problem Solving with DSA - Day 47: Under the Hood | Internal Working of Python Dictionaries 🛠️🐍* ->Welcome to Day 47 of my 60-Day DSA Challenge! Today, we are cracking open the Python Dictionary to see how it achieves that lightning-fast O(1) speed. 🏗️ The Architecture: Buckets & Key-Value Pairs ->In Python, a dictionary is essentially a Hash Table. When you do my_dict["name"] = "Sriman", here is what happens: ->Hashing: Python calls the hash() function on your key ("name"). This generates a large integer. ->Indexing: It takes that integer and performs a modulo operation with the current size of the hash table: index = hash("name") % array_size. ->Storage: It stores the key, the hash value, and the actual value in a "Bucket" at that index. ⚔️ Collision Handling in Python: Open Addressing ->Unlike Java (which uses Chaining/Linked Lists), Python uses Open Addressing with a special probing technique. ->If a collision occurs (two keys map to the same index), Python doesn't create a list. ->Instead, it looks for another empty slot using a Pseudo-random Probing sequence. This keeps the data "flat" and cache-friendly. 📈 Dynamic Resizing: The Load Factor ->A HashMap works best when it's not too full. ->Load Factor: It’s the ratio of (number of items) / (table size). ->Resizing: When the dictionary gets about 2/3rd full, Python automatically creates a larger table (usually 2x or 4x the size) and re-hashes all existing keys into the new table. This ensures operations stay O(1). 💻 Python Code: Simulating the Logic # How Python sees your data key = "Day47" value = "HashMap Internal" # 1. Get Hash h = hash(key) # 2. Map to Index (Simplified) capacity = 8 index = h & (capacity - 1) # Efficient bitwise way to do modulo print(f"Key: {key} hashes to index: {index}") 📊 Python Dict Optimization (Compact Dict): ->Since Python 3.6+, dictionaries are ordered by default. They use a split-table design (an indices array and an entries array) which saves a lot of memory. 🧠 Challenge of the Day: ->"If Python uses Open Addressing, what happens to the search time if we keep adding elements without ever resizing the table? Why is the 2/3rd threshold important?" 📈 Progress Tracking: Current Topic: Dictionary Internals Status: Day 47/60 ✅ (78% Complete!) Next Up: Handling Collisions Understanding the 'Internal Magic' makes you a better developer, not just a coder mama! Ready to apply this speed to some real interview problems tomorrow? 👇 #60DaysOfCode #Python #HashMap #Hashing #SoftwareEngineering #InternalWorking #BigO #DataStructures #Algorithms #PlacementPrep #TechEducation
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development